mirror of
https://github.com/hmalik144/Driver.git
synced 2025-12-10 02:45:20 +00:00
- refactoring of admin app
- file structure updated Took 34 hours 38 minutes
This commit is contained in:
@@ -79,7 +79,7 @@ jobs:
|
|||||||
parameters:
|
parameters:
|
||||||
flavour:
|
flavour:
|
||||||
type: string
|
type: string
|
||||||
default: ""
|
default: "Driver"
|
||||||
executor:
|
executor:
|
||||||
name: android/android-machine
|
name: android/android-machine
|
||||||
steps:
|
steps:
|
||||||
@@ -101,7 +101,7 @@ workflows:
|
|||||||
build-release-driver:
|
build-release-driver:
|
||||||
jobs:
|
jobs:
|
||||||
- build-and-test:
|
- build-and-test:
|
||||||
flavour: Driver
|
flavour: "Driver"
|
||||||
- assemble-and-release:
|
- assemble-and-release:
|
||||||
flavour: "Driver"
|
flavour: "Driver"
|
||||||
filters:
|
filters:
|
||||||
@@ -113,9 +113,9 @@ workflows:
|
|||||||
build-release-admin:
|
build-release-admin:
|
||||||
jobs:
|
jobs:
|
||||||
- build-and-test:
|
- build-and-test:
|
||||||
flavour: Admin
|
flavour: "Admin"
|
||||||
- assemble-and-release:
|
- assemble-and-release:
|
||||||
flavour: Admin
|
flavour: "Admin"
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
only: main_admin
|
only: main_admin
|
||||||
|
|||||||
@@ -66,22 +66,25 @@ android {
|
|||||||
flavorDimensions "Default"
|
flavorDimensions "Default"
|
||||||
productFlavors {
|
productFlavors {
|
||||||
driver {
|
driver {
|
||||||
|
applicationId "h_mal.appttude.com.driver"
|
||||||
versionCode 7
|
versionCode 7
|
||||||
versionName "2.0.0"
|
versionName "2.0.0"
|
||||||
}
|
}
|
||||||
admin {
|
admin {
|
||||||
applicationIdSuffix ".admin"
|
applicationId "h_mal.appttude.com.driver.admin"
|
||||||
versionCode 4
|
versionCode 4
|
||||||
versionName "0.0.5"
|
versionName "0.0.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourceSets {
|
sourceSets {
|
||||||
driver {
|
driver {
|
||||||
|
java.srcDirs += 'src/driver/java'
|
||||||
manifest {
|
manifest {
|
||||||
srcFile 'src/driver/AndroidManifest.xml'
|
srcFile 'src/driver/AndroidManifest.xml'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
admin {
|
admin {
|
||||||
|
java.srcDirs += 'src/admin/java'
|
||||||
manifest {
|
manifest {
|
||||||
srcFile 'src/admin/AndroidManifest.xml'
|
srcFile 'src/admin/AndroidManifest.xml'
|
||||||
}
|
}
|
||||||
@@ -108,6 +111,7 @@ dependencies {
|
|||||||
implementation 'androidx.viewpager:viewpager:1.0.0'
|
implementation 'androidx.viewpager:viewpager:1.0.0'
|
||||||
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||||
testImplementation "junit:junit:4.13.2"
|
testImplementation "junit:junit:4.13.2"
|
||||||
|
implementation "androidx.preference:preference-ktx:1.2.0"
|
||||||
/ * Android Espresso */
|
/ * Android Espresso */
|
||||||
def testJunitVersion = "1.1.5"
|
def testJunitVersion = "1.1.5"
|
||||||
def testRunnerVersion = "1.5.2"
|
def testRunnerVersion = "1.5.2"
|
||||||
@@ -128,6 +132,7 @@ dependencies {
|
|||||||
implementation "com.google.firebase:firebase-auth:$firebaseAuth"
|
implementation "com.google.firebase:firebase-auth:$firebaseAuth"
|
||||||
implementation "com.google.firebase:firebase-storage:$firebaseStorage"
|
implementation "com.google.firebase:firebase-storage:$firebaseStorage"
|
||||||
implementation "com.google.firebase:firebase-database:$firebaseDatabase"
|
implementation "com.google.firebase:firebase-database:$firebaseDatabase"
|
||||||
|
implementation 'com.firebaseui:firebase-ui-database:8.0.2'
|
||||||
/ * Photoviewer */
|
/ * Photoviewer */
|
||||||
implementation "com.github.chrisbanes:PhotoView:2.1.0"
|
implementation "com.github.chrisbanes:PhotoView:2.1.0"
|
||||||
/ * Picasso photo loader */
|
/ * Picasso photo loader */
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<!-- To auto-complete the email text field in the login form with the user's emails -->
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
||||||
|
|
||||||
<application
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
|
||||||
android:roundIcon="@mipmap/ic_launcher_round">
|
|
||||||
|
|
||||||
</application>
|
|
||||||
|
|
||||||
</manifest>
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package h_mal.appttude.com.driver.application
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseAuthSource
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||||
|
import h_mal.appttude.com.driver.data.prefs.PreferenceProvider
|
||||||
|
import h_mal.appttude.com.driver.viewmodels.*
|
||||||
|
|
||||||
|
class ApplicationViewModelFactory(
|
||||||
|
private val auth: FirebaseAuthSource,
|
||||||
|
private val database: FirebaseDatabaseSource,
|
||||||
|
private val storage: FirebaseStorageSource,
|
||||||
|
private val preferences: PreferenceProvider
|
||||||
|
) : ViewModelProvider.Factory {
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
|
with(modelClass) {
|
||||||
|
return when {
|
||||||
|
isAssignableFrom(UserViewModel::class.java) -> UserViewModel(auth)
|
||||||
|
isAssignableFrom(MainViewModel::class.java) -> MainViewModel(auth, database)
|
||||||
|
isAssignableFrom(UpdateUserViewModel::class.java) -> UpdateUserViewModel(
|
||||||
|
auth,
|
||||||
|
storage
|
||||||
|
)
|
||||||
|
isAssignableFrom(RoleViewModel::class.java) -> RoleViewModel(
|
||||||
|
auth,
|
||||||
|
database,
|
||||||
|
storage
|
||||||
|
)
|
||||||
|
|
||||||
|
isAssignableFrom(DriverLicenseViewModel::class.java) -> DriverLicenseViewModel(
|
||||||
|
database
|
||||||
|
)
|
||||||
|
isAssignableFrom(DriverProfileViewModel::class.java) -> DriverProfileViewModel(
|
||||||
|
database
|
||||||
|
)
|
||||||
|
isAssignableFrom(PrivateHireLicenseViewModel::class.java) -> PrivateHireLicenseViewModel(
|
||||||
|
database
|
||||||
|
)
|
||||||
|
isAssignableFrom(VehicleProfileViewModel::class.java) -> VehicleProfileViewModel(
|
||||||
|
database
|
||||||
|
)
|
||||||
|
isAssignableFrom(InsuranceViewModel::class.java) -> InsuranceViewModel(database)
|
||||||
|
isAssignableFrom(MotViewModel::class.java) -> MotViewModel(database)
|
||||||
|
isAssignableFrom(LogbookViewModel::class.java) -> LogbookViewModel(database)
|
||||||
|
isAssignableFrom(PrivateHireVehicleViewModel::class.java) -> PrivateHireVehicleViewModel(
|
||||||
|
database
|
||||||
|
)
|
||||||
|
isAssignableFrom(DriverOverviewViewModel::class.java) -> DriverOverviewViewModel(
|
||||||
|
auth,
|
||||||
|
database
|
||||||
|
)
|
||||||
|
isAssignableFrom(SuperUserViewModel::class.java) -> SuperUserViewModel(
|
||||||
|
database,
|
||||||
|
preferences
|
||||||
|
)
|
||||||
|
else -> throw IllegalArgumentException("Unknown ViewModel class")
|
||||||
|
} as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package h_mal.appttude.com.driver.base
|
||||||
|
|
||||||
|
import com.google.firebase.database.DatabaseReference
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseCompletion
|
||||||
|
import h_mal.appttude.com.driver.utils.Coroutines.io
|
||||||
|
import h_mal.appttude.com.driver.utils.GenericsHelper.getGenericClassAt
|
||||||
|
import h_mal.appttude.com.driver.utils.getDataFromDatabaseRef
|
||||||
|
import h_mal.appttude.com.driver.utils.isNotNull
|
||||||
|
|
||||||
|
abstract class DataViewerBaseViewModel<T : Any> : BaseViewModel() {
|
||||||
|
var uid: String? = null
|
||||||
|
|
||||||
|
abstract fun getDatabaseRef(uid: String): DatabaseReference
|
||||||
|
|
||||||
|
fun initViewModel(uid: String) {
|
||||||
|
this.uid = uid
|
||||||
|
retrieveData(uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fetchData() {
|
||||||
|
@Suppress("IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION")
|
||||||
|
uid.isNotNull {
|
||||||
|
retrieveData(it)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
onError("Failed to retrieve data for user")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun retrieveData(uid: String) {
|
||||||
|
val clazz = getGenericClassAt<T>(0)
|
||||||
|
io {
|
||||||
|
doTryOperation("Failed to retrieve ${clazz.simpleName}") {
|
||||||
|
val data = getDatabaseRef(uid).getDataFromDatabaseRef(clazz.java)
|
||||||
|
onSuccess(data ?: FirebaseCompletion.Default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package h_mal.appttude.com.driver.base
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.CheckBox
|
||||||
|
import android.widget.EditText
|
||||||
|
import androidx.core.view.children
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
import h_mal.appttude.com.driver.data.USER_CONST
|
||||||
|
import h_mal.appttude.com.driver.utils.GenericsHelper.getGenericClassAt
|
||||||
|
import h_mal.appttude.com.driver.utils.hide
|
||||||
|
import h_mal.appttude.com.driver.utils.isTrue
|
||||||
|
|
||||||
|
open class DataViewerFragment<V : DataViewerBaseViewModel<T>, VB : ViewBinding, T : Any> :
|
||||||
|
BaseFragment<V, VB>() {
|
||||||
|
|
||||||
|
override fun setupView(binding: VB) {
|
||||||
|
super.setupView(binding)
|
||||||
|
|
||||||
|
(binding.root as ViewGroup).children.forEach { disableViews(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun disableViews(view: View) {
|
||||||
|
if (view is EditText)
|
||||||
|
view.isFocusable = false
|
||||||
|
if (view is CheckBox)
|
||||||
|
view.isFocusable = false
|
||||||
|
else if (view is ViewGroup)
|
||||||
|
view.children.forEach { disableViews(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
requireArguments().getString(USER_CONST)?.let {
|
||||||
|
viewModel.initViewModel(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
override fun onSuccess(data: Any?) {
|
||||||
|
super.onSuccess(data)
|
||||||
|
|
||||||
|
data?.let { (data::class == getGenericClassAt<T>(2)) }?.isTrue {
|
||||||
|
setFields(data as T)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun setFields(data: T) {}
|
||||||
|
|
||||||
|
fun viewsToHide(vararg view: View) {
|
||||||
|
view.forEach { it.hide() }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package h_mal.appttude.com.driver.model
|
||||||
|
|
||||||
|
enum class SortOption(val key: String, val label: String) {
|
||||||
|
NAME("driver_profile/driver_details/forenames","Driver Name"),
|
||||||
|
NUMBER("driver_number", "Driver Number");
|
||||||
|
// APPROVAL("forenames")
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getSortOptionByLabel(label: String?): SortOption? {
|
||||||
|
return values().firstOrNull { i -> i.label == label }
|
||||||
|
}
|
||||||
|
fun getPositionByLabel(label: String?): Int? {
|
||||||
|
val sortOption = getSortOptionByLabel(label) ?: return null
|
||||||
|
return values().indexOf(sortOption)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,34 +1,13 @@
|
|||||||
package h_mal.appttude.com.driver.admin.objects
|
package h_mal.appttude.com.driver.objects
|
||||||
|
|
||||||
|
|
||||||
class ApprovalsObject {
|
data class ApprovalsObject (
|
||||||
var driver_details_approval: Int = 0
|
var driver_details_approval: Int = 0,
|
||||||
var driver_license_approval: Int = 0
|
var driver_license_approval: Int = 0,
|
||||||
var private_hire_approval: Int = 0
|
var private_hire_approval: Int = 0,
|
||||||
var vehicle_details_approval: Int = 0
|
var vehicle_details_approval: Int = 0,
|
||||||
var mot_details_approval: Int = 0
|
var mot_details_approval: Int = 0,
|
||||||
var insurance_details_approval: Int = 0
|
var insurance_details_approval: Int = 0,
|
||||||
var log_book_approval: Int = 0
|
var log_book_approval: Int = 0,
|
||||||
var ph_car_approval: Int = 0
|
var ph_car_approval: Int = 0,
|
||||||
|
)
|
||||||
constructor()
|
|
||||||
constructor(
|
|
||||||
driver_details_approval: Int,
|
|
||||||
driver_license_approval: Int,
|
|
||||||
private_hire_approval: Int,
|
|
||||||
vehicle_details_approval: Int,
|
|
||||||
mot_details_approval: Int,
|
|
||||||
insurance_details_approval: Int,
|
|
||||||
log_book_approval: Int,
|
|
||||||
private_hire_vehicle_approval: Int
|
|
||||||
) {
|
|
||||||
this.driver_details_approval = driver_details_approval
|
|
||||||
this.driver_license_approval = driver_license_approval
|
|
||||||
this.private_hire_approval = private_hire_approval
|
|
||||||
this.vehicle_details_approval = vehicle_details_approval
|
|
||||||
this.mot_details_approval = mot_details_approval
|
|
||||||
this.insurance_details_approval = insurance_details_approval
|
|
||||||
this.log_book_approval = log_book_approval
|
|
||||||
this.ph_car_approval = private_hire_vehicle_approval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +1,14 @@
|
|||||||
package h_mal.appttude.com.driver.admin.objects
|
package h_mal.appttude.com.driver.objects
|
||||||
|
|
||||||
import h_mal.appttude.com.driver.model.*
|
import h_mal.appttude.com.driver.model.*
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class ArchiveObject {
|
|
||||||
var driver_license: HashMap<String, DriversLicense>? = null
|
|
||||||
var private_hire: HashMap<String, PrivateHireLicense>? = null
|
|
||||||
var vehicle_details: HashMap<String, VehicleProfile>? = null
|
|
||||||
var insurance_details: HashMap<String, Insurance>? = null
|
|
||||||
var mot_details: HashMap<String, Mot>? = null
|
|
||||||
var log_book: HashMap<String, Logbook>? = null
|
|
||||||
var ph_car: HashMap<String, PrivateHireVehicle>? = null
|
|
||||||
|
|
||||||
constructor()
|
data class ArchiveObject(
|
||||||
constructor(
|
var driver_license: HashMap<String, DriversLicense>? = HashMap(),
|
||||||
driver_license: HashMap<String, DriversLicense>?,
|
var private_hire: HashMap<String, PrivateHireLicense>? = HashMap(),
|
||||||
private_hire: HashMap<String, PrivateHireLicense>?,
|
var vehicle_details: HashMap<String, VehicleProfile>? = HashMap(),
|
||||||
vehicle_details: HashMap<String, VehicleProfile>?,
|
var insurance_details: HashMap<String, Insurance>? = HashMap(),
|
||||||
insurance_details: HashMap<String, Insurance>?,
|
var mot_details: HashMap<String, Mot>? = HashMap(),
|
||||||
mot_details: HashMap<String, Mot>?,
|
var log_book: HashMap<String, Logbook>? = HashMap(),
|
||||||
log_book: HashMap<String, Logbook>?,
|
var ph_car: HashMap<String, PrivateHireVehicle>? = HashMap(),
|
||||||
private_hire_vehicle: HashMap<String, PrivateHireVehicle>?
|
)
|
||||||
) {
|
|
||||||
this.driver_license = driver_license
|
|
||||||
this.private_hire = private_hire
|
|
||||||
this.vehicle_details = vehicle_details
|
|
||||||
this.insurance_details = insurance_details
|
|
||||||
this.mot_details = mot_details
|
|
||||||
this.log_book = log_book
|
|
||||||
this.ph_car = private_hire_vehicle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,10 @@
|
|||||||
package h_mal.appttude.com.driver.admin.objects
|
package h_mal.appttude.com.driver.objects
|
||||||
|
|
||||||
|
import com.google.firebase.database.IgnoreExtraProperties
|
||||||
|
|
||||||
class UserObject {
|
@IgnoreExtraProperties
|
||||||
var profileName: String? = null
|
data class UserObject (
|
||||||
var profileEmail: String? = null
|
var profileName: String? = "",
|
||||||
var profilePicString: String? = null
|
var profileEmail: String? = "",
|
||||||
|
var profilePicString: String? = "",
|
||||||
constructor()
|
)
|
||||||
constructor(profileName: String?, profileEmail: String?, profilePicString: String?) {
|
|
||||||
this.profileName = profileName
|
|
||||||
this.profileEmail = profileEmail
|
|
||||||
this.profilePicString = profilePicString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +1,15 @@
|
|||||||
package h_mal.appttude.com.driver.admin.objects
|
package h_mal.appttude.com.driver.objects
|
||||||
|
|
||||||
import h_mal.appttude.com.driver.admin.objects.wholeObject.DriverProfile
|
import h_mal.appttude.com.driver.objects.wholeObject.DriverProfile
|
||||||
import h_mal.appttude.com.driver.admin.objects.wholeObject.VehicleProfile
|
import h_mal.appttude.com.driver.objects.wholeObject.VehicleProfile
|
||||||
|
|
||||||
|
|
||||||
class WholeDriverObject {
|
data class WholeDriverObject(
|
||||||
var driver_profile: DriverProfile? = null
|
var driver_profile: DriverProfile? = DriverProfile(),
|
||||||
var role: String? = null
|
var role: String? = "",
|
||||||
var archive: ArchiveObject? = null
|
var archive: ArchiveObject? = ArchiveObject(),
|
||||||
var user_details: UserObject? = null
|
var user_details: UserObject? = UserObject(),
|
||||||
var vehicle_profile: VehicleProfile? = null
|
var vehicle_profile: VehicleProfile? = VehicleProfile(),
|
||||||
var approvalsObject: ApprovalsObject? = null
|
var approvalsObject: ApprovalsObject? = ApprovalsObject(),
|
||||||
var driver_number: String? = null
|
var driver_number: String? = "",
|
||||||
|
)
|
||||||
constructor(
|
|
||||||
driver_profile: DriverProfile?,
|
|
||||||
role: String?,
|
|
||||||
archive: ArchiveObject?,
|
|
||||||
user_details: UserObject?,
|
|
||||||
vehicle_profile: VehicleProfile?,
|
|
||||||
approvalsObject: ApprovalsObject?,
|
|
||||||
driver_number: String?
|
|
||||||
) {
|
|
||||||
this.driver_profile = driver_profile
|
|
||||||
this.role = role
|
|
||||||
this.archive = archive
|
|
||||||
this.user_details = user_details
|
|
||||||
this.vehicle_profile = vehicle_profile
|
|
||||||
this.approvalsObject = approvalsObject
|
|
||||||
this.driver_number = driver_number
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor()
|
|
||||||
}
|
|
||||||
@@ -1,24 +1,12 @@
|
|||||||
package h_mal.appttude.com.driver.admin.objects.wholeObject
|
package h_mal.appttude.com.driver.objects.wholeObject
|
||||||
|
|
||||||
import h_mal.appttude.com.driver.model.DriverProfile
|
import h_mal.appttude.com.driver.model.DriverProfile
|
||||||
import h_mal.appttude.com.driver.model.DriversLicense
|
import h_mal.appttude.com.driver.model.DriversLicense
|
||||||
import h_mal.appttude.com.driver.model.PrivateHireLicense
|
import h_mal.appttude.com.driver.model.PrivateHireLicense
|
||||||
|
|
||||||
|
|
||||||
class DriverProfile {
|
data class DriverProfile(
|
||||||
var driver_profile: DriverProfile? = null
|
var driver_profile: DriverProfile? = DriverProfile(),
|
||||||
var driver_license: DriversLicense? = null
|
var driver_license: DriversLicense? = DriversLicense(),
|
||||||
var private_hire: PrivateHireLicense? = null
|
var private_hire: PrivateHireLicense? = PrivateHireLicense(),
|
||||||
|
)
|
||||||
constructor(
|
|
||||||
driver_profile: DriverProfile?,
|
|
||||||
driver_license: DriversLicense?,
|
|
||||||
private_hire: PrivateHireLicense?
|
|
||||||
) {
|
|
||||||
this.driver_profile = driver_profile
|
|
||||||
this.driver_license = driver_license
|
|
||||||
this.private_hire = private_hire
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor()
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package h_mal.appttude.com.driver.admin.objects.wholeObject
|
|
||||||
|
|
||||||
import android.os.Parcel
|
|
||||||
import android.os.Parcelable
|
|
||||||
import h_mal.appttude.com.driver.admin.objects.WholeDriverObject
|
|
||||||
|
|
||||||
|
|
||||||
class MappedObject : Parcelable {
|
|
||||||
var userId: String? = null
|
|
||||||
var wholeDriverObject: WholeDriverObject? = null
|
|
||||||
|
|
||||||
constructor(userId: String?, wholeDriverObject: WholeDriverObject?) {
|
|
||||||
this.userId = userId
|
|
||||||
this.wholeDriverObject = wholeDriverObject
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor()
|
|
||||||
protected constructor(`in`: Parcel) {
|
|
||||||
userId = `in`.readString()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun describeContents(): Int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
|
||||||
dest.writeString(userId)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmField
|
|
||||||
val CREATOR: Parcelable.Creator<MappedObject?> =
|
|
||||||
object : Parcelable.Creator<MappedObject?> {
|
|
||||||
override fun createFromParcel(`in`: Parcel): MappedObject? {
|
|
||||||
return MappedObject(`in`)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun newArray(size: Int): Array<MappedObject?> {
|
|
||||||
return arrayOfNulls(size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +1,12 @@
|
|||||||
package h_mal.appttude.com.driver.admin.objects.wholeObject
|
package h_mal.appttude.com.driver.objects.wholeObject
|
||||||
|
|
||||||
import h_mal.appttude.com.driver.model.Insurance
|
import h_mal.appttude.com.driver.model.*
|
||||||
import h_mal.appttude.com.driver.model.Logbook
|
|
||||||
import h_mal.appttude.com.driver.model.PrivateHireVehicle
|
|
||||||
import h_mal.appttude.com.driver.model.Mot
|
|
||||||
import h_mal.appttude.com.driver.model.VehicleProfile
|
import h_mal.appttude.com.driver.model.VehicleProfile
|
||||||
|
|
||||||
|
data class VehicleProfile (
|
||||||
class VehicleProfile {
|
var insurance_details: Insurance? = Insurance(),
|
||||||
var insurance_details: Insurance? = null
|
var log_book: Logbook? = Logbook(),
|
||||||
var log_book: Logbook? = null
|
var mot_details: Mot? = Mot(),
|
||||||
var mot_details: Mot? = null
|
var vehicle_details: VehicleProfile? = VehicleProfile(),
|
||||||
var vehicle_details: VehicleProfile? = null
|
var privateHireVehicle: PrivateHireVehicle? = PrivateHireVehicle()
|
||||||
var privateHireVehicle: PrivateHireVehicle? = null
|
)
|
||||||
|
|
||||||
constructor()
|
|
||||||
constructor(
|
|
||||||
insurance_details: Insurance?,
|
|
||||||
log_book: Logbook?,
|
|
||||||
mot_details: Mot?,
|
|
||||||
vehicle_details: VehicleProfile?,
|
|
||||||
private_hire_vehicle: PrivateHireVehicle?
|
|
||||||
) {
|
|
||||||
this.insurance_details = insurance_details
|
|
||||||
this.log_book = log_book
|
|
||||||
this.mot_details = mot_details
|
|
||||||
this.vehicle_details = vehicle_details
|
|
||||||
this.privateHireVehicle = private_hire_vehicle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,188 +1,77 @@
|
|||||||
package h_mal.appttude.com.driver.ui
|
package h_mal.appttude.com.driver.ui
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.BaseAdapter
|
||||||
import h_mal.appttude.com.driver.admin.objects.wholeObject.MappedObject
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import h_mal.appttude.com.driver.R
|
import h_mal.appttude.com.driver.R
|
||||||
|
import h_mal.appttude.com.driver.databinding.ApprovalListItemBinding
|
||||||
|
import h_mal.appttude.com.driver.utils.hide
|
||||||
|
|
||||||
|
|
||||||
class ApprovalListAdapter(
|
class ApprovalListAdapter(
|
||||||
private val activity: Activity,
|
private val layoutInflater: LayoutInflater,
|
||||||
objects: Array<MappedObject?>
|
private var approvals: Map<String, Int?>,
|
||||||
) : ArrayAdapter<MappedObject?>(activity, 0, objects) {
|
private val callback: (String) -> Unit
|
||||||
|
) : BaseAdapter() {
|
||||||
|
override fun getCount(): Int = approvals.size
|
||||||
|
override fun getItem(position: Int): Map.Entry<String, Int?> = approvals.entries.elementAt(position)
|
||||||
|
override fun getItemId(position: Int): Long = position.toLong()
|
||||||
|
|
||||||
var mappedObject: MappedObject? = objects[0]
|
|
||||||
|
|
||||||
var names: Array<String> = arrayOf(
|
|
||||||
"Driver Profile",
|
|
||||||
"Driver License",
|
|
||||||
"Private Hire",
|
|
||||||
"Vehicle Profile",
|
|
||||||
"Insurance",
|
|
||||||
"MOT",
|
|
||||||
"Logbook",
|
|
||||||
"P/H Vehicle"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
var approvalCode: Int = 0
|
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||||
var listItemView: View? = convertView
|
var listItemView: View? = convertView
|
||||||
|
val binding: ApprovalListItemBinding
|
||||||
if (listItemView == null) {
|
if (listItemView == null) {
|
||||||
listItemView = LayoutInflater.from(activity).inflate(
|
binding = ApprovalListItemBinding.inflate(layoutInflater, parent, false)
|
||||||
R.layout.approval_list_grid_item, parent, false
|
listItemView = binding.root
|
||||||
)
|
listItemView.setTag(listItemView.id, binding)
|
||||||
|
} else {
|
||||||
|
binding = listItemView.getTag(listItemView.id) as ApprovalListItemBinding
|
||||||
|
}
|
||||||
|
|
||||||
|
val key = getItem(position).key
|
||||||
|
val itemValue = getItem(position).value
|
||||||
|
|
||||||
|
binding.approvalText.text = key
|
||||||
|
if (itemValue != 0) {
|
||||||
|
binding.root.setOnClickListener { callback.invoke(key) }
|
||||||
|
}
|
||||||
|
binding.approvalIv.setImageResource(getImageResourceBasedOnApproval(itemValue))
|
||||||
|
binding.approvalStatus.text = listItemView.context.getString(getStringResourceBasedOnApproval(itemValue))
|
||||||
|
|
||||||
|
if (position == 0) {
|
||||||
|
binding.divider.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (listItemView)
|
||||||
|
}
|
||||||
|
@DrawableRes
|
||||||
|
private fun getImageResourceBasedOnApproval(value: Int?): Int {
|
||||||
|
return when(value) {
|
||||||
|
0 -> R.drawable.denied
|
||||||
|
1 -> R.drawable.denied
|
||||||
|
2 -> R.drawable.pending
|
||||||
|
3 -> R.drawable.approved
|
||||||
|
else -> R.drawable.pending
|
||||||
}
|
}
|
||||||
// approvalCode = getApprovalStatusCode(position)
|
|
||||||
// val textView: TextView = listItemView!!.findViewById(R.id.approval_text)
|
|
||||||
// textView.text = names.get(position)
|
|
||||||
// val imageView: ImageView = listItemView.findViewById(R.id.approval_iv)
|
|
||||||
// imageView.setImageResource(
|
|
||||||
// MainActivity.approvalsClass!!.setImageResource(
|
|
||||||
// approvalCode
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// imageView.setOnClickListener {
|
|
||||||
// SetApprovalDialog(
|
|
||||||
// approvalCode,
|
|
||||||
// activity,
|
|
||||||
// mappedObject.userId,
|
|
||||||
// position,
|
|
||||||
// imageView
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// val archiveImage: ImageView = listItemView.findViewById(R.id.archive_icon)
|
|
||||||
// mappedObject.wholeDriverObject?.archive?.let {
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// archiveImage.visibility = getArchive(
|
|
||||||
// position,
|
|
||||||
// it
|
|
||||||
// )
|
|
||||||
// archiveImage.setOnClickListener {
|
|
||||||
// var s: String? = null
|
|
||||||
// when (position) {
|
|
||||||
// 1 -> s = FirebaseClass.DRIVERS_LICENSE_FIREBASE
|
|
||||||
// 2 -> s = FirebaseClass.PRIVATE_HIRE_FIREBASE
|
|
||||||
// 3 -> s = FirebaseClass.VEHICLE_DETAILS_FIREBASE
|
|
||||||
// 4 -> s = FirebaseClass.INSURANCE_FIREBASE
|
|
||||||
// 5 -> s = FirebaseClass.MOT_FIREBASE
|
|
||||||
// 6 -> s = FirebaseClass.LOG_BOOK_FIREBASE
|
|
||||||
// 7 -> s = FirebaseClass.PRIVATE_HIRE_VEHICLE_LICENSE
|
|
||||||
// }
|
|
||||||
//// executeFragment(ArchiveFragment(), mappedObject.userId, s)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// listItemView.setOnClickListener(View.OnClickListener { getFragment(position) })
|
|
||||||
// listItemView.minimumHeight = parent.height / 4
|
|
||||||
// listItemView.setPadding(
|
|
||||||
// convertDpToPixel(9f, context).toInt(),
|
|
||||||
// convertDpToPixel(9f, context).toInt(),
|
|
||||||
// convertDpToPixel(9f, context).toInt(),
|
|
||||||
// convertDpToPixel(9f, context).toInt()
|
|
||||||
// )
|
|
||||||
return (listItemView)!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// override fun getCount(): Int {
|
@StringRes
|
||||||
// return 8
|
private fun getStringResourceBasedOnApproval(value: Int?): Int {
|
||||||
// }
|
return when(value) {
|
||||||
//
|
0 -> R.string.not_submitted
|
||||||
// private fun getArchive(i: Int, archiveObject: ArchiveObject?): Int {
|
1 -> R.string.denied
|
||||||
// var o: Any? = null
|
2 -> R.string.pending
|
||||||
// val visible: Int
|
3 -> R.string.approved
|
||||||
// when (i) {
|
else -> R.string.pending
|
||||||
// 0 -> { }
|
}
|
||||||
// 1 -> o = archiveObject!!.driver_license
|
}
|
||||||
// 2 -> o = archiveObject!!.private_hire
|
|
||||||
// 3 -> o = archiveObject!!.vehicle_details
|
|
||||||
// 4 -> o = archiveObject!!.insurance_details
|
|
||||||
// 5 -> o = archiveObject!!.mot_details
|
|
||||||
// 6 -> o = archiveObject!!.log_book
|
|
||||||
// 7 -> o = archiveObject!!.ph_car
|
|
||||||
// }
|
|
||||||
// if (o != null) {
|
|
||||||
// visible = View.VISIBLE
|
|
||||||
// } else {
|
|
||||||
// visible = View.GONE
|
|
||||||
// }
|
|
||||||
// return visible
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private fun getFragment(i: Int) {
|
|
||||||
// lateinit var f: Fragment
|
|
||||||
// val driverProfile by lazy { mappedObject.wholeDriverObject?.driver_profile }
|
|
||||||
// val vehicleProfile by lazy { mappedObject.wholeDriverObject?.vehicle_profile }
|
|
||||||
// val o: Any? = when (i) {
|
|
||||||
// 0 -> {
|
|
||||||
// f = DriverProfileFragment()
|
|
||||||
// driverProfile?.driver_profile
|
|
||||||
// }
|
|
||||||
// 1 -> {
|
|
||||||
// f = DriverLicenseFragment()
|
|
||||||
// driverProfile?.driver_license
|
|
||||||
// }
|
|
||||||
// 2 -> {
|
|
||||||
// f = PrivateHireLicenseFragment()
|
|
||||||
// driverProfile?.private_hire
|
|
||||||
// }
|
|
||||||
// 3 -> {
|
|
||||||
// f = VehicleProfileFragment()
|
|
||||||
// vehicleProfile?.vehicle_details
|
|
||||||
// }
|
|
||||||
// 4 -> {
|
|
||||||
// f = InsuranceFragment()
|
|
||||||
// vehicleProfile?.insurance_details
|
|
||||||
// }
|
|
||||||
// 5 -> {
|
|
||||||
// f = MotFragment()
|
|
||||||
// vehicleProfile?.insurance_details
|
|
||||||
// }
|
|
||||||
// 6 -> {
|
|
||||||
// f = LogbookFragment()
|
|
||||||
// vehicleProfile?.log_book
|
|
||||||
// }
|
|
||||||
// 7 -> {
|
|
||||||
// f = PrivateHireVehicleFragment()
|
|
||||||
// vehicleProfile?.privateHireVehicleObject
|
|
||||||
// }
|
|
||||||
// else -> null
|
|
||||||
// }
|
|
||||||
// if (o == null) {
|
|
||||||
//// executeFragment(f, mappedObject.userId)
|
|
||||||
// } else {
|
|
||||||
// MainActivity.archiveClass.openDialogArchive(
|
|
||||||
// context, o, mappedObject.userId, f
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private fun getApprovalStatusCode(i: Int): Int {
|
|
||||||
// val statusCode = mappedObject.wholeDriverObject?.approvalsObject?.let{
|
|
||||||
// when (i) {
|
|
||||||
// 0 -> it.driver_details_approval
|
|
||||||
// 1 -> it.driver_license_approval
|
|
||||||
// 2 -> it.private_hire_approval
|
|
||||||
// 3 -> it.vehicle_details_approval
|
|
||||||
// 4 -> it.insurance_details_approval
|
|
||||||
// 5 -> it.mot_details_approval
|
|
||||||
// 6 -> it.log_book_approval
|
|
||||||
// 7 -> it.ph_car_approval
|
|
||||||
// else -> FirebaseClass.NO_DATE_PRESENT
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return statusCode ?: FirebaseClass.NO_DATE_PRESENT
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// companion object {
|
|
||||||
// fun convertDpToPixel(dp: Float, context: Context): Float {
|
|
||||||
// return dp * (context.resources
|
|
||||||
// .displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
fun updateAdapter(data: Map<String, Int?>) {
|
||||||
|
approvals = data
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package h_mal.appttude.com.driver.ui
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.ListView
|
||||||
|
import h_mal.appttude.com.driver.R
|
||||||
|
import h_mal.appttude.com.driver.base.BaseFragment
|
||||||
|
import h_mal.appttude.com.driver.data.USER_CONST
|
||||||
|
import h_mal.appttude.com.driver.databinding.FragmentUserMainBinding
|
||||||
|
import h_mal.appttude.com.driver.utils.navigateTo
|
||||||
|
import h_mal.appttude.com.driver.utils.toBundle
|
||||||
|
import h_mal.appttude.com.driver.viewmodels.DriverOverviewViewModel
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
|
||||||
|
class DriverOverviewFragment : BaseFragment<DriverOverviewViewModel, FragmentUserMainBinding>() {
|
||||||
|
|
||||||
|
private lateinit var listView: ListView
|
||||||
|
private lateinit var driverId: String
|
||||||
|
|
||||||
|
override fun setupView(binding: FragmentUserMainBinding) {
|
||||||
|
listView = binding.approvalsList
|
||||||
|
|
||||||
|
driverId = requireArguments().getString(USER_CONST) ?: throw IOException("No user ID has been passed")
|
||||||
|
viewModel.loadDriverApprovals(driverId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSuccess(data: Any?) {
|
||||||
|
super.onSuccess(data)
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
if (data is Map<*, *>) {
|
||||||
|
if (listView.adapter == null) {
|
||||||
|
listView.adapter = ApprovalListAdapter(layoutInflater, data as Map<String, Int?>) {
|
||||||
|
this.view?.applyNavigation(it)
|
||||||
|
}
|
||||||
|
listView.isScrollContainer = false
|
||||||
|
} else {
|
||||||
|
(listView.adapter as ApprovalListAdapter).updateAdapter(data as Map<String, Int?>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun View.applyNavigation(key: String) {
|
||||||
|
val navId = when (key) {
|
||||||
|
context.getString(R.string.driver_profile) -> R.id.to_driverProfileFragment
|
||||||
|
context.getString(R.string.drivers_license) -> R.id.to_driverLicenseFragment
|
||||||
|
context.getString(R.string.private_hire_license) -> R.id.to_privateHireLicenseFragment
|
||||||
|
context.getString(R.string.vehicle_profile) -> R.id.to_vehicleProfileFragment
|
||||||
|
context.getString(R.string.insurance) -> R.id.to_insuranceFragment
|
||||||
|
context.getString(R.string.m_o_t) -> R.id.to_motFragment
|
||||||
|
context.getString(R.string.log_book) -> R.id.to_logbookFragment
|
||||||
|
context.getString(R.string.private_hire_vehicle_license) -> R.id.to_privateHireVehicleFragment
|
||||||
|
else -> {
|
||||||
|
throw StringIndexOutOfBoundsException("No resource for $key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
navigateTo(navId, driverId.toBundle(USER_CONST))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,153 +1,158 @@
|
|||||||
package h_mal.appttude.com.driver.ui
|
package h_mal.appttude.com.driver.ui
|
||||||
|
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import androidx.fragment.app.Fragment
|
import android.widget.EditText
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import android.widget.LinearLayout
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.core.view.MenuProvider
|
||||||
import com.google.firebase.database.DataSnapshot
|
import androidx.lifecycle.Lifecycle
|
||||||
import com.google.firebase.database.DatabaseError
|
import com.firebase.ui.database.FirebaseRecyclerAdapter
|
||||||
import com.google.firebase.database.DatabaseReference
|
import com.firebase.ui.database.FirebaseRecyclerOptions
|
||||||
import com.google.firebase.database.ValueEventListener
|
|
||||||
import h_mal.appttude.com.driver.admin.objects.WholeDriverObject
|
|
||||||
import h_mal.appttude.com.driver.admin.objects.wholeObject.MappedObject
|
|
||||||
import h_mal.appttude.com.driver.R
|
import h_mal.appttude.com.driver.R
|
||||||
import java.io.IOException
|
import h_mal.appttude.com.driver.base.BaseFirebaseAdapter
|
||||||
|
import h_mal.appttude.com.driver.base.BaseFragment
|
||||||
|
import h_mal.appttude.com.driver.base.CustomViewHolder
|
||||||
|
import h_mal.appttude.com.driver.data.USER_CONST
|
||||||
|
import h_mal.appttude.com.driver.databinding.FragmentHomeSuperUserBinding
|
||||||
|
import h_mal.appttude.com.driver.databinding.ListItemLayoutBinding
|
||||||
|
import h_mal.appttude.com.driver.model.SortOption
|
||||||
|
import h_mal.appttude.com.driver.objects.UserObject
|
||||||
|
import h_mal.appttude.com.driver.objects.WholeDriverObject
|
||||||
|
import h_mal.appttude.com.driver.utils.*
|
||||||
|
import h_mal.appttude.com.driver.viewmodels.SuperUserViewModel
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class HomeSuperUserFragment : Fragment() {
|
class HomeSuperUserFragment : BaseFragment<SuperUserViewModel, FragmentHomeSuperUserBinding>(), MenuProvider {
|
||||||
var users: DatabaseReference? = null
|
private lateinit var adapter: FirebaseRecyclerAdapter<WholeDriverObject, CustomViewHolder<ListItemLayoutBinding>>
|
||||||
var mappedObjectList: MutableList<MappedObject>? = null
|
|
||||||
private var sharedPreferences: SharedPreferences? = null
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
private var sortOrder: Int = 0
|
super.onViewCreated(view, savedInstanceState)
|
||||||
private val sortDesc: Boolean = false
|
requireActivity().addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.RESUMED)
|
||||||
private var recyclerViewAdapter: RecyclerViewAdapter? = null
|
viewModel.retrieveDefaultFirebaseOptions()
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
setHasOptionsMenu(true)
|
|
||||||
mappedObjectList = ArrayList()
|
|
||||||
users!!.addValueEventListener(valueEventListener)
|
|
||||||
sharedPreferences = requireActivity().getSharedPreferences("PREFS", 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onSuccess(data: Any?) {
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
super.onSuccess(data)
|
||||||
savedInstanceState: Bundle?
|
when (data) {
|
||||||
): View? {
|
is FirebaseRecyclerOptions<*> -> setAdapterToRecyclerView(data)
|
||||||
// Inflate the layout for this fragment
|
|
||||||
val view: View = inflater.inflate(R.layout.fragment_home_super_user, container, false)
|
|
||||||
|
|
||||||
view.findViewById<RecyclerView>(R.id.recycler_view).apply {
|
|
||||||
layoutManager = LinearLayoutManager(context)
|
|
||||||
recyclerViewAdapter = RecyclerViewAdapter(context, mappedObjectList)
|
|
||||||
adapter = recyclerViewAdapter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return view
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var valueEventListener: ValueEventListener = object : ValueEventListener {
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun onDataChange(snapshot: DataSnapshot) {
|
private fun setAdapterToRecyclerView(options: FirebaseRecyclerOptions<*>) {
|
||||||
mappedObjectList!!.clear()
|
applyBinding {
|
||||||
Log.i("Count ", "" + snapshot.childrenCount)
|
progressCircular.show()
|
||||||
for (postSnapshot: DataSnapshot in snapshot.children) {
|
if (recyclerView.adapter == null) {
|
||||||
if ((postSnapshot.child("role").value.toString() == "driver")) {
|
// create an adapter for the first time
|
||||||
mappedObjectList!!.add(
|
adapter = createAdapter(options = options as FirebaseRecyclerOptions<WholeDriverObject>)
|
||||||
MappedObject(
|
recyclerView.adapter = adapter
|
||||||
postSnapshot.key, postSnapshot.getValue(
|
recyclerView.setHasFixedSize(true)
|
||||||
WholeDriverObject::class.java
|
adapter.startListening()
|
||||||
)
|
} else {
|
||||||
|
adapter.updateOptions(options as FirebaseRecyclerOptions<WholeDriverObject>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
adapter.stopListening()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createAdapter(options: FirebaseRecyclerOptions<WholeDriverObject>): BaseFirebaseAdapter<WholeDriverObject, ListItemLayoutBinding> {
|
||||||
|
return object : BaseFirebaseAdapter<WholeDriverObject, ListItemLayoutBinding>(options, layoutInflater) {
|
||||||
|
|
||||||
|
override fun onBindViewHolder(
|
||||||
|
holder: CustomViewHolder<ListItemLayoutBinding>,
|
||||||
|
position: Int,
|
||||||
|
model: WholeDriverObject
|
||||||
|
) {
|
||||||
|
val userDetails: UserObject? = model.user_details
|
||||||
|
holder.viewBinding.apply {
|
||||||
|
driverPic.setGlideImage(userDetails?.profilePicString)
|
||||||
|
usernameText.text = userDetails?.profileName
|
||||||
|
emailaddressText.text = userDetails?.profileEmail
|
||||||
|
driverNo.run {
|
||||||
|
val number = model.driver_number ?: "0"
|
||||||
|
text = number
|
||||||
|
setOnClickListener {
|
||||||
|
val uid = getKeyAtPosition(position)
|
||||||
|
if (uid != null) {
|
||||||
|
showChangeNumberDialog(uid, number)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
root.setOnClickListener {
|
||||||
|
it.navigateTo(
|
||||||
|
R.id.action_homeAdminFragment_to_userMainFragment,
|
||||||
|
snapshots.getSnapshot(position).key?.toBundle(USER_CONST)
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sortDate(sortOrder, sortDesc)
|
|
||||||
|
|
||||||
}
|
override fun onDataChanged() {
|
||||||
|
super.onDataChanged()
|
||||||
override fun onCancelled(databaseError: DatabaseError) {
|
applyBinding {
|
||||||
|
// If there are no chat messages, show a view that invites the user to add a message.
|
||||||
}
|
if (itemCount == 0) {
|
||||||
}
|
emptyView.root.visibility = if (itemCount == 0) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
|
||||||
inflater.inflate(R.menu.menu_calls_fragment, menu)
|
|
||||||
super.onCreateOptionsMenu(menu, inflater)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
||||||
if (item.itemId == R.id.archive) {
|
|
||||||
val grpname: Array<String> = arrayOf("Driver Name", "Driver Number", "Approval")
|
|
||||||
sortOrder = sharedPreferences!!.getInt(SORT, 0)
|
|
||||||
val checkedItem: Int = sortOrder
|
|
||||||
var compareInt = 0
|
|
||||||
val click = DialogInterface.OnClickListener { dialog, _ ->
|
|
||||||
sortDate(compareInt, false)
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
val builder: AlertDialog.Builder = AlertDialog.Builder(context)
|
|
||||||
builder.setTitle("Sort by:")
|
|
||||||
.setSingleChoiceItems(
|
|
||||||
grpname,
|
|
||||||
checkedItem
|
|
||||||
) { _, pos -> compareInt = pos }
|
|
||||||
.setPositiveButton("Ascending", click)
|
|
||||||
.setNegativeButton("Descending", click)
|
|
||||||
.create().show()
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun sortDate(compareInt: Int, reversed: Boolean) {
|
|
||||||
val comparator: Comparator<MappedObject> = object : Comparator<MappedObject> {
|
|
||||||
override fun compare(o1: MappedObject, o2: MappedObject): Int {
|
|
||||||
when (compareInt) {
|
|
||||||
0 -> return o1.wholeDriverObject?.user_details?.profileName!!.compareTo(
|
|
||||||
o2.wholeDriverObject?.user_details?.profileName!!
|
|
||||||
)
|
|
||||||
1 -> {
|
|
||||||
var s1: String? = o1.wholeDriverObject?.driver_number
|
|
||||||
var s2: String? = o2.wholeDriverObject?.driver_number
|
|
||||||
if (o1.wholeDriverObject?.driver_number == null || (o1.wholeDriverObject!!
|
|
||||||
.driver_number == "0")
|
|
||||||
) {
|
|
||||||
s1 = ";"
|
|
||||||
}
|
|
||||||
if (o2.wholeDriverObject?.driver_number == null || (o2.wholeDriverObject!!
|
|
||||||
.driver_number == "0")
|
|
||||||
) {
|
|
||||||
s2 = ";"
|
|
||||||
}
|
|
||||||
return s1!!.compareTo((s2)!!)
|
|
||||||
}
|
}
|
||||||
else -> {
|
|
||||||
throw IOException("dfdfs")
|
progressCircular.hide()
|
||||||
}
|
|
||||||
// 2 -> return MainActivity.approvalsClass.getOverApprovalStatusCode(o1.wholeDriverObject) -
|
|
||||||
// MainActivity.approvalsClass.getOverApprovalStatusCode(o2.wholeDriverObject)
|
|
||||||
// else -> return MainActivity.approvalsClass.getOverApprovalStatusCode(
|
|
||||||
// o1.wholeDriverObject
|
|
||||||
// ) - MainActivity.approvalsClass.getOverApprovalStatusCode(o2.wholeDriverObject)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun connectionLost() {
|
||||||
|
requireContext().displayToast("No connection available")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sharedPreferences!!.edit().putInt(SORT, compareInt).apply()
|
|
||||||
sharedPreferences!!.edit().putBoolean(REVERSED, reversed).apply()
|
|
||||||
if (reversed) {
|
|
||||||
Collections.sort(mappedObjectList, comparator.reversed())
|
|
||||||
} else {
|
|
||||||
Collections.sort(mappedObjectList, comparator)
|
|
||||||
}
|
|
||||||
recyclerViewAdapter!!.notifyDataSetChanged()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
private fun showChangeNumberDialog(defaultNumber: String, uid: String) {
|
||||||
private val SORT: String = "SORT"
|
val inputText = EditText(context).apply {
|
||||||
private val REVERSED: String = "REVERSED"
|
setText(defaultNumber)
|
||||||
|
setSelectAllOnFocus(true)
|
||||||
|
}
|
||||||
|
val layout = LinearLayout(context).apply {
|
||||||
|
orientation = LinearLayout.VERTICAL
|
||||||
|
setPadding(28, 0, 56, 0)
|
||||||
|
addView(inputText)
|
||||||
|
}
|
||||||
|
|
||||||
|
AlertDialog.Builder(context).setTitle("Change Driver Number")
|
||||||
|
.setView(layout)
|
||||||
|
.setPositiveButton("Submit") { _, _ ->
|
||||||
|
val input = inputText.text?.toString()
|
||||||
|
viewModel.updateDriverNumber(uid, input)
|
||||||
|
}.create().show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||||
|
menuInflater.inflate(R.menu.menu_calls_fragment, menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||||
|
if (menuItem.itemId == R.id.archive) {
|
||||||
|
displaySortOptions()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun displaySortOptions() {
|
||||||
|
val groupName: Array<String> = arrayOf("Driver Name", "Driver Number")
|
||||||
|
val defaultPosition = viewModel.getSelectionAsPosition()
|
||||||
|
val builder: AlertDialog.Builder = AlertDialog.Builder(context)
|
||||||
|
builder.setTitle("Sort by:")
|
||||||
|
.setSingleChoiceItems(
|
||||||
|
groupName,
|
||||||
|
defaultPosition
|
||||||
|
) { _, pos ->
|
||||||
|
val option = SortOption.getSortOptionByLabel(groupName[pos])
|
||||||
|
viewModel.createFirebaseOptions(sort = option)
|
||||||
|
}
|
||||||
|
.create().show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
package h_mal.appttude.com.driver.ui
|
|
||||||
|
|
||||||
import android.app.AlertDialog
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.EditText
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import com.squareup.picasso.Picasso
|
|
||||||
import h_mal.appttude.com.driver.admin.objects.UserObject
|
|
||||||
import h_mal.appttude.com.driver.admin.objects.wholeObject.MappedObject
|
|
||||||
import h_mal.appttude.com.driver.R
|
|
||||||
|
|
||||||
|
|
||||||
class RecyclerViewAdapter constructor(var context: Context?, var objects: List<MappedObject>?) :
|
|
||||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
|
||||||
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): RecyclerView.ViewHolder {
|
|
||||||
val viewCurrent: View =
|
|
||||||
LayoutInflater.from(context).inflate(R.layout.list_item_layout, viewGroup, false)
|
|
||||||
return ViewHolderMain(viewCurrent)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, i: Int) {
|
|
||||||
val viewHolderCurrent: ViewHolderMain = viewHolder as ViewHolderMain
|
|
||||||
val mappedObject: MappedObject = objects!!.get(i)
|
|
||||||
val `object`: UserObject? = mappedObject.wholeDriverObject?.user_details
|
|
||||||
if (`object`!!.profilePicString != null) {
|
|
||||||
Picasso.get()
|
|
||||||
.load(`object`.profilePicString)
|
|
||||||
.resize(128, 128)
|
|
||||||
.placeholder(R.drawable.choice_img_round)
|
|
||||||
.into(viewHolderCurrent.profilePicImage)
|
|
||||||
} else {
|
|
||||||
viewHolderCurrent.profilePicImage.setImageResource(R.drawable.choice_img_round)
|
|
||||||
}
|
|
||||||
viewHolderCurrent.userNameTextView.setText(`object`.profileName)
|
|
||||||
viewHolderCurrent.userEmailTextView.setText(`object`.profileEmail)
|
|
||||||
if (mappedObject.wholeDriverObject?.driver_number == null) {
|
|
||||||
viewHolderCurrent.driverNo.text = "0"
|
|
||||||
} else {
|
|
||||||
val s: String = mappedObject.wholeDriverObject?.driver_number.toString()
|
|
||||||
viewHolderCurrent.driverNo.text = s
|
|
||||||
}
|
|
||||||
viewHolderCurrent.driverNo.setOnClickListener {
|
|
||||||
val builder: AlertDialog.Builder = AlertDialog.Builder(
|
|
||||||
context
|
|
||||||
)
|
|
||||||
val input: EditText = EditText(context)
|
|
||||||
val layout: LinearLayout = LinearLayout(context)
|
|
||||||
layout.orientation = LinearLayout.VERTICAL
|
|
||||||
layout.setPadding(28, 0, 56, 0)
|
|
||||||
input.setText(viewHolderCurrent.driverNo.text.toString())
|
|
||||||
input.setSelectAllOnFocus(true)
|
|
||||||
layout.addView(input)
|
|
||||||
builder.setTitle("Change Driver Number")
|
|
||||||
.setView(layout)
|
|
||||||
.setPositiveButton(
|
|
||||||
"Submit"
|
|
||||||
) { dialog, which ->
|
|
||||||
|
|
||||||
}.create()
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
// viewHolderCurrent.profileApprovalImage.setImageResource(
|
|
||||||
// MainActivity.approvalsClass!!.getOverApprovalStatusCode(mappedObject.wholeDriverObject)
|
|
||||||
// )
|
|
||||||
viewHolderCurrent.itemView.setOnClickListener {
|
|
||||||
val bundle: Bundle = Bundle()
|
|
||||||
bundle.putParcelable("mapped", mappedObject)
|
|
||||||
// executeFragment(UserMainFragment(), bundle)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
|
||||||
return objects!!.size
|
|
||||||
}
|
|
||||||
|
|
||||||
internal inner class ViewHolderMain constructor(listItemView: View) :
|
|
||||||
RecyclerView.ViewHolder(listItemView) {
|
|
||||||
var profilePicImage: ImageView
|
|
||||||
var userNameTextView: TextView
|
|
||||||
var userEmailTextView: TextView
|
|
||||||
|
|
||||||
// CardView statusCard;
|
|
||||||
var profileApprovalImage: ImageView
|
|
||||||
var driverNo: TextView
|
|
||||||
|
|
||||||
init {
|
|
||||||
profilePicImage = listItemView.findViewById(R.id.driverPic)
|
|
||||||
userNameTextView = listItemView.findViewById(R.id.username_text)
|
|
||||||
// statusCard = listItemView.findViewById(R.id.status_icon);
|
|
||||||
userEmailTextView = listItemView.findViewById(R.id.emailaddress_text)
|
|
||||||
profileApprovalImage = listItemView.findViewById(R.id.approval_iv)
|
|
||||||
driverNo = listItemView.findViewById(R.id.driver_no)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package h_mal.appttude.com.driver.ui
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.GridView
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import h_mal.appttude.com.driver.admin.objects.wholeObject.MappedObject
|
|
||||||
import h_mal.appttude.com.driver.R
|
|
||||||
|
|
||||||
|
|
||||||
class UserMainFragment : Fragment() {
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View? {
|
|
||||||
// Inflate the layout for this fragment
|
|
||||||
val view: View = inflater.inflate(R.layout.fragment_user_main, container, false)
|
|
||||||
Log.i("UserMain", "onCreateView: height = " + view.height)
|
|
||||||
val mappedObject: MappedObject? = requireArguments().getParcelable<MappedObject>("mapped")
|
|
||||||
activity?.title = mappedObject?.wholeDriverObject?.user_details?.profileName
|
|
||||||
|
|
||||||
val listView: GridView = view.findViewById(R.id.approvals_list)
|
|
||||||
listView.adapter = ApprovalListAdapter(requireActivity(), arrayOf(mappedObject))
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package h_mal.appttude.com.driver.ui.driverprofile
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerFragment
|
||||||
|
import h_mal.appttude.com.driver.databinding.FragmentDriverLicenseBinding
|
||||||
|
import h_mal.appttude.com.driver.model.DriversLicense
|
||||||
|
import h_mal.appttude.com.driver.utils.setGlideImage
|
||||||
|
import h_mal.appttude.com.driver.viewmodels.DriverLicenseViewModel
|
||||||
|
|
||||||
|
class DriverLicenseFragment :
|
||||||
|
DataViewerFragment<DriverLicenseViewModel, FragmentDriverLicenseBinding, DriversLicense>() {
|
||||||
|
|
||||||
|
override fun setupView(binding: FragmentDriverLicenseBinding) {
|
||||||
|
super.setupView(binding)
|
||||||
|
viewsToHide(binding.submit, binding.searchImage)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setFields(data: DriversLicense) {
|
||||||
|
super.setFields(data)
|
||||||
|
applyBinding {
|
||||||
|
driversliImg.setGlideImage(data.licenseImageString)
|
||||||
|
licNo.setText(data.licenseNumber)
|
||||||
|
licExpiry.setText(data.licenseExpiry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package h_mal.appttude.com.driver.ui.driverprofile
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerFragment
|
||||||
|
import h_mal.appttude.com.driver.databinding.FragmentDriverProfileBinding
|
||||||
|
import h_mal.appttude.com.driver.model.DriverProfile
|
||||||
|
import h_mal.appttude.com.driver.utils.setGlideImage
|
||||||
|
import h_mal.appttude.com.driver.viewmodels.DriverProfileViewModel
|
||||||
|
|
||||||
|
|
||||||
|
class DriverProfileFragment :
|
||||||
|
DataViewerFragment<DriverProfileViewModel, FragmentDriverProfileBinding, DriverProfile>() {
|
||||||
|
|
||||||
|
override fun setupView(binding: FragmentDriverProfileBinding) {
|
||||||
|
super.setupView(binding)
|
||||||
|
viewsToHide(binding.submitDriver, binding.addPhoto)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setFields(data: DriverProfile) {
|
||||||
|
super.setFields(data)
|
||||||
|
applyBinding {
|
||||||
|
driverPic.setGlideImage(data.driverPic)
|
||||||
|
namesInput.setText(data.forenames)
|
||||||
|
addressInput.setText(data.address)
|
||||||
|
postcodeInput.setText(data.postcode)
|
||||||
|
dobInput.setText(data.dob)
|
||||||
|
niNumber.setText(data.ni)
|
||||||
|
dateFirst.setText(data.dateFirst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package h_mal.appttude.com.driver.ui.driverprofile
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerFragment
|
||||||
|
import h_mal.appttude.com.driver.databinding.FragmentPrivateHireLicenseBinding
|
||||||
|
import h_mal.appttude.com.driver.model.PrivateHireLicense
|
||||||
|
import h_mal.appttude.com.driver.utils.setGlideImage
|
||||||
|
import h_mal.appttude.com.driver.viewmodels.PrivateHireLicenseViewModel
|
||||||
|
|
||||||
|
|
||||||
|
class PrivateHireLicenseFragment : DataViewerFragment<PrivateHireLicenseViewModel, FragmentPrivateHireLicenseBinding, PrivateHireLicense>() {
|
||||||
|
|
||||||
|
override fun setupView(binding: FragmentPrivateHireLicenseBinding) {
|
||||||
|
super.setupView(binding)
|
||||||
|
viewsToHide(binding.submit, binding.uploadphlic)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setFields(data: PrivateHireLicense) {
|
||||||
|
super.setFields(data)
|
||||||
|
applyBinding {
|
||||||
|
imageView2.setGlideImage(data.phImageString)
|
||||||
|
phNo.setText(data.phNumber)
|
||||||
|
phExpiry.setText(data.phExpiry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package h_mal.appttude.com.driver.ui.vehicleprofile
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import android.widget.ImageView
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerFragment
|
||||||
|
import h_mal.appttude.com.driver.databinding.FragmentInsuranceBinding
|
||||||
|
import h_mal.appttude.com.driver.model.Insurance
|
||||||
|
import h_mal.appttude.com.driver.utils.setGlideImage
|
||||||
|
import h_mal.appttude.com.driver.viewmodels.InsuranceViewModel
|
||||||
|
|
||||||
|
|
||||||
|
class InsuranceFragment :
|
||||||
|
DataViewerFragment<InsuranceViewModel, FragmentInsuranceBinding, Insurance>() {
|
||||||
|
|
||||||
|
override fun setupView(binding: FragmentInsuranceBinding) {
|
||||||
|
super.setupView(binding)
|
||||||
|
viewsToHide(binding.submitIns, binding.uploadInsurance)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun updateImageCarousal(list: List<Any?>) {
|
||||||
|
applyBinding {
|
||||||
|
carouselView.setImageClickListener(null)
|
||||||
|
carouselView.setImageListener { i: Int, imageView: ImageView ->
|
||||||
|
when (list[i]) {
|
||||||
|
is Uri -> {
|
||||||
|
imageView.setGlideImage(list[i] as Uri)
|
||||||
|
}
|
||||||
|
is String -> imageView.setGlideImage(list[i] as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
carouselView.pageCount = list.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setFields(data: Insurance) {
|
||||||
|
super.setFields(data)
|
||||||
|
applyBinding {
|
||||||
|
insurer.setText(data.insurerName)
|
||||||
|
insuranceExp.setText(data.expiryDate)
|
||||||
|
data.photoStrings?.let { updateImageCarousal(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package h_mal.appttude.com.driver.ui.vehicleprofile
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerFragment
|
||||||
|
import h_mal.appttude.com.driver.databinding.FragmentLogbookBinding
|
||||||
|
import h_mal.appttude.com.driver.model.Logbook
|
||||||
|
import h_mal.appttude.com.driver.utils.setGlideImage
|
||||||
|
import h_mal.appttude.com.driver.viewmodels.LogbookViewModel
|
||||||
|
|
||||||
|
|
||||||
|
class LogbookFragment :
|
||||||
|
DataViewerFragment<LogbookViewModel, FragmentLogbookBinding, Logbook>() {
|
||||||
|
|
||||||
|
override fun setupView(binding: FragmentLogbookBinding) {
|
||||||
|
super.setupView(binding)
|
||||||
|
viewsToHide(binding.submitLb, binding.uploadLb)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setFields(data: Logbook) {
|
||||||
|
super.setFields(data)
|
||||||
|
applyBinding {
|
||||||
|
logBookImg.setGlideImage(data.photoString)
|
||||||
|
v5cNo.setText(data.v5cnumber)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package h_mal.appttude.com.driver.ui.vehicleprofile
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerFragment
|
||||||
|
import h_mal.appttude.com.driver.databinding.FragmentMotBinding
|
||||||
|
import h_mal.appttude.com.driver.model.Mot
|
||||||
|
import h_mal.appttude.com.driver.utils.setGlideImage
|
||||||
|
import h_mal.appttude.com.driver.viewmodels.MotViewModel
|
||||||
|
|
||||||
|
|
||||||
|
class MotFragment : DataViewerFragment<MotViewModel, FragmentMotBinding, Mot>() {
|
||||||
|
|
||||||
|
override fun setupView(binding: FragmentMotBinding) {
|
||||||
|
super.setupView(binding)
|
||||||
|
viewsToHide(binding.submitMot, binding.uploadmot)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setFields(data: Mot) {
|
||||||
|
super.setFields(data)
|
||||||
|
applyBinding {
|
||||||
|
motImg.setGlideImage(data.motImageString)
|
||||||
|
motExpiry.setText(data.motExpiry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package h_mal.appttude.com.driver.ui.vehicleprofile
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerFragment
|
||||||
|
import h_mal.appttude.com.driver.databinding.FragmentPrivateHireLicenseBinding
|
||||||
|
import h_mal.appttude.com.driver.model.PrivateHireVehicle
|
||||||
|
import h_mal.appttude.com.driver.utils.setGlideImage
|
||||||
|
import h_mal.appttude.com.driver.viewmodels.PrivateHireVehicleViewModel
|
||||||
|
|
||||||
|
|
||||||
|
class PrivateHireVehicleFragment :
|
||||||
|
DataViewerFragment<PrivateHireVehicleViewModel, FragmentPrivateHireLicenseBinding, PrivateHireVehicle>() {
|
||||||
|
|
||||||
|
override fun setupView(binding: FragmentPrivateHireLicenseBinding) {
|
||||||
|
super.setupView(binding)
|
||||||
|
viewsToHide(binding.submit, binding.uploadphlic)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setFields(data: PrivateHireVehicle) {
|
||||||
|
super.setFields(data)
|
||||||
|
applyBinding {
|
||||||
|
imageView2.setGlideImage(data.phCarImageString)
|
||||||
|
phNo.setText(data.phCarNumber)
|
||||||
|
phExpiry.setText(data.phCarExpiry)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package h_mal.appttude.com.driver.ui.vehicleprofile
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerFragment
|
||||||
|
import h_mal.appttude.com.driver.databinding.FragmentVehicleSetupBinding
|
||||||
|
import h_mal.appttude.com.driver.model.VehicleProfile
|
||||||
|
import h_mal.appttude.com.driver.viewmodels.VehicleProfileViewModel
|
||||||
|
|
||||||
|
|
||||||
|
class VehicleProfileFragment :
|
||||||
|
DataViewerFragment<VehicleProfileViewModel, FragmentVehicleSetupBinding, VehicleProfile>() {
|
||||||
|
|
||||||
|
override fun setupView(binding: FragmentVehicleSetupBinding) {
|
||||||
|
super.setupView(binding)
|
||||||
|
viewsToHide(binding.submitVehicle)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setFields(data: VehicleProfile) {
|
||||||
|
super.setFields(data)
|
||||||
|
applyBinding {
|
||||||
|
reg.setText(data.reg)
|
||||||
|
make.setText(data.make)
|
||||||
|
carModel.setText(data.model)
|
||||||
|
colour.setText(data.colour)
|
||||||
|
keeperName.setText(data.keeperName)
|
||||||
|
address.setText(data.keeperAddress)
|
||||||
|
postcode.setText(data.keeperPostCode)
|
||||||
|
startDate.setText(data.startDate)
|
||||||
|
seizedCheckbox.isChecked = data.isSeized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package h_mal.appttude.com.driver.viewmodels
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerBaseViewModel
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
|
import h_mal.appttude.com.driver.model.DriversLicense
|
||||||
|
|
||||||
|
class DriverLicenseViewModel(
|
||||||
|
private val database: FirebaseDatabaseSource
|
||||||
|
) : DataViewerBaseViewModel<DriversLicense>() {
|
||||||
|
|
||||||
|
override fun getDatabaseRef(uid: String) = database.getDriverLicenseRef(uid)
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package h_mal.appttude.com.driver.viewmodels
|
||||||
|
|
||||||
|
import com.google.firebase.database.DatabaseReference
|
||||||
|
import com.google.firebase.storage.StorageReference
|
||||||
|
import h_mal.appttude.com.driver.base.DataSubmissionBaseViewModel
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseAuthentication
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
|
import h_mal.appttude.com.driver.objects.ApprovalsObject
|
||||||
|
import h_mal.appttude.com.driver.utils.Coroutines.io
|
||||||
|
import h_mal.appttude.com.driver.utils.getDataFromDatabaseRef
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
|
||||||
|
class DriverOverviewViewModel(
|
||||||
|
auth: FirebaseAuthentication,
|
||||||
|
private val database: FirebaseDatabaseSource
|
||||||
|
) : DataSubmissionBaseViewModel<ApprovalsObject>(auth, database, null) {
|
||||||
|
|
||||||
|
private var driverId: String? = null
|
||||||
|
|
||||||
|
override val databaseRef: DatabaseReference = database.getApprovalsRef(driverId ?: "")
|
||||||
|
override val storageRef: StorageReference? = null
|
||||||
|
override val objectName: String = "Approvals"
|
||||||
|
|
||||||
|
override fun getDataFromDatabase(): Job = retrieveDataFromDatabase<ApprovalsObject>()
|
||||||
|
|
||||||
|
fun loadDriverApprovals(driverId: String?) {
|
||||||
|
this.driverId = driverId
|
||||||
|
io {
|
||||||
|
doTryOperation("Failed to retrieve $objectName") {
|
||||||
|
val data = driverId?.let {
|
||||||
|
database.getApprovalsRef(it).getDataFromDatabaseRef()
|
||||||
|
} ?: ApprovalsObject()
|
||||||
|
val mappedData = mapApprovalsForView(data)
|
||||||
|
onSuccess(mappedData)
|
||||||
|
return@doTryOperation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mapApprovalsForView(data: ApprovalsObject): Map<String, Int> {
|
||||||
|
return mutableMapOf<String, Int>().apply {
|
||||||
|
put("Driver Profile", data.driver_details_approval)
|
||||||
|
put("Drivers License", data.driver_license_approval)
|
||||||
|
put("Private Hire License", data.private_hire_approval)
|
||||||
|
put("Vehicle Profile", data.vehicle_details_approval)
|
||||||
|
put("Insurance", data.insurance_details_approval)
|
||||||
|
put("M.O.T", data.mot_details_approval)
|
||||||
|
put("Log book", data.log_book_approval)
|
||||||
|
put("Private Hire Vehicle License", data.ph_car_approval)
|
||||||
|
}.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package h_mal.appttude.com.driver.viewmodels
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerBaseViewModel
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
|
import h_mal.appttude.com.driver.model.DriverProfile
|
||||||
|
|
||||||
|
class DriverProfileViewModel(
|
||||||
|
private val database: FirebaseDatabaseSource
|
||||||
|
) : DataViewerBaseViewModel<DriverProfile>() {
|
||||||
|
override fun getDatabaseRef(uid: String) = database.getDriverDetailsRef(uid)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package h_mal.appttude.com.driver.viewmodels
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerBaseViewModel
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
|
import h_mal.appttude.com.driver.model.Insurance
|
||||||
|
|
||||||
|
class InsuranceViewModel(
|
||||||
|
private val database: FirebaseDatabaseSource
|
||||||
|
) : DataViewerBaseViewModel<Insurance>() {
|
||||||
|
|
||||||
|
override fun getDatabaseRef(uid: String) = database.getInsuranceDetailsRef(uid)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package h_mal.appttude.com.driver.viewmodels
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerBaseViewModel
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
|
import h_mal.appttude.com.driver.model.Logbook
|
||||||
|
|
||||||
|
class LogbookViewModel(
|
||||||
|
private val database: FirebaseDatabaseSource
|
||||||
|
) : DataViewerBaseViewModel<Logbook>() {
|
||||||
|
|
||||||
|
override fun getDatabaseRef(uid: String) = database.getLogbookRef(uid)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package h_mal.appttude.com.driver.viewmodels
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerBaseViewModel
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
|
import h_mal.appttude.com.driver.model.Mot
|
||||||
|
|
||||||
|
class MotViewModel(
|
||||||
|
private val database: FirebaseDatabaseSource
|
||||||
|
) : DataViewerBaseViewModel<Mot>() {
|
||||||
|
|
||||||
|
override fun getDatabaseRef(uid: String) = database.getMotDetailsRef(uid)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package h_mal.appttude.com.driver.viewmodels
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerBaseViewModel
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
|
import h_mal.appttude.com.driver.model.PrivateHireLicense
|
||||||
|
|
||||||
|
class PrivateHireLicenseViewModel(
|
||||||
|
private val database: FirebaseDatabaseSource
|
||||||
|
) : DataViewerBaseViewModel<PrivateHireLicense>() {
|
||||||
|
|
||||||
|
override fun getDatabaseRef(uid: String) = database.getPrivateHireRef(uid)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package h_mal.appttude.com.driver.viewmodels
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerBaseViewModel
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
|
import h_mal.appttude.com.driver.model.PrivateHireVehicle
|
||||||
|
|
||||||
|
class PrivateHireVehicleViewModel(
|
||||||
|
private val database: FirebaseDatabaseSource
|
||||||
|
) : DataViewerBaseViewModel<PrivateHireVehicle>() {
|
||||||
|
|
||||||
|
override fun getDatabaseRef(uid: String) = database.getPrivateHireVehicleRef(uid)
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package h_mal.appttude.com.driver.viewmodels
|
||||||
|
|
||||||
|
import com.firebase.ui.database.FirebaseRecyclerOptions
|
||||||
|
import h_mal.appttude.com.driver.base.BaseViewModel
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
|
import h_mal.appttude.com.driver.data.prefs.PreferenceProvider
|
||||||
|
import h_mal.appttude.com.driver.model.SortOption
|
||||||
|
import h_mal.appttude.com.driver.objects.WholeDriverObject
|
||||||
|
import h_mal.appttude.com.driver.utils.Coroutines.io
|
||||||
|
import h_mal.appttude.com.driver.utils.isNotNull
|
||||||
|
|
||||||
|
|
||||||
|
class SuperUserViewModel(
|
||||||
|
private val firebaseDatabaseSource: FirebaseDatabaseSource,
|
||||||
|
private val preferenceProvider: PreferenceProvider
|
||||||
|
) : BaseViewModel() {
|
||||||
|
|
||||||
|
fun retrieveDefaultFirebaseOptions() {
|
||||||
|
val optionLabel = preferenceProvider.getSortOption()
|
||||||
|
val option = SortOption.getSortOptionByLabel(optionLabel)
|
||||||
|
createFirebaseOptions(option)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createFirebaseOptions(sort: SortOption? = null) {
|
||||||
|
val ref = firebaseDatabaseSource.getUsersRef()
|
||||||
|
|
||||||
|
sort?.isNotNull { preferenceProvider.setSortOption(it.label) }
|
||||||
|
|
||||||
|
// val query = when(sort) {
|
||||||
|
// NAME, NUMBER -> ref.orderByChild(sort.key)
|
||||||
|
//// SortOption.APPROVAL -> TODO()
|
||||||
|
// else -> ref.orderByKey()
|
||||||
|
// }
|
||||||
|
|
||||||
|
val options = FirebaseRecyclerOptions.Builder<WholeDriverObject>()
|
||||||
|
.setQuery(ref.orderByKey(), WholeDriverObject::class.java)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
onSuccess(options)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateDriverNumber(uid: String, input: String?) {
|
||||||
|
io {
|
||||||
|
doTryOperation("failed update driver identifier") {
|
||||||
|
// validate input
|
||||||
|
if (input.isNullOrBlank()) {
|
||||||
|
onError("No driver identifier provided")
|
||||||
|
return@doTryOperation
|
||||||
|
}
|
||||||
|
firebaseDatabaseSource.postToDatabaseRed(firebaseDatabaseSource.getUserRef(uid), input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSelectionAsPosition(): Int {
|
||||||
|
val optionLabel = preferenceProvider.getSortOption()
|
||||||
|
return SortOption.getPositionByLabel(optionLabel) ?: -1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package h_mal.appttude.com.driver.viewmodels
|
||||||
|
|
||||||
|
import h_mal.appttude.com.driver.base.DataViewerBaseViewModel
|
||||||
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
|
import h_mal.appttude.com.driver.model.VehicleProfile
|
||||||
|
|
||||||
|
class VehicleProfileViewModel(
|
||||||
|
private val database: FirebaseDatabaseSource
|
||||||
|
) : DataViewerBaseViewModel<VehicleProfile>() {
|
||||||
|
|
||||||
|
override fun getDatabaseRef(uid: String) = database.getVehicleDetailsRef(uid)
|
||||||
|
}
|
||||||
63
app/src/admin/res/layout/approval_list_item.xml
Normal file
63
app/src/admin/res/layout/approval_list_item.xml
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@color/colour_ten"
|
||||||
|
android:paddingEnd="28dp"
|
||||||
|
app:layout_constraintLeft_toLeftOf="@id/approval_status"
|
||||||
|
app:layout_constraintRight_toRightOf="@id/approval_status"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:ignore="RtlSymmetry" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/approval_iv"
|
||||||
|
android:layout_width="@dimen/status_size"
|
||||||
|
android:layout_height="@dimen/status_size"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="28dp"
|
||||||
|
android:layout_marginTop="9dp"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:src="@drawable/pending"
|
||||||
|
android:contentDescription="@string/approval_status" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/approval_status"
|
||||||
|
style="@style/subheader"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginLeft="28dp"
|
||||||
|
android:layout_marginRight="28dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/approval_iv"
|
||||||
|
app:layout_constraintLeft_toRightOf="@id/approval_iv"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/approval_iv"
|
||||||
|
tools:text="Pending Approval" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/approval_text"
|
||||||
|
style="@style/headerStyle"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="0dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:paddingBottom="9dp"
|
||||||
|
app:layout_constraintLeft_toLeftOf="@id/approval_status"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/approval_status"
|
||||||
|
tools:text="Private Hire License" />
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
16
app/src/admin/res/layout/empty_layout.xml
Normal file
16
app/src/admin/res/layout/empty_layout.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/empty_view_message"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -1,16 +1,42 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
tools:context=".ui.HomeSuperUserFragment">
|
tools:context=".ui.HomeSuperUserFragment">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
android:orientation="vertical"
|
||||||
tools:listitem="@layout/list_item_layout">
|
tools:listitem="@layout/list_item_layout">
|
||||||
|
|
||||||
</androidx.recyclerview.widget.RecyclerView>
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
|
|
||||||
</RelativeLayout>
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_circular"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/empty_view"
|
||||||
|
layout="@layout/empty_layout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -1,17 +1,32 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
style="@style/parent_constraint_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ui.UserMainFragment">
|
tools:context=".ui.DriverOverviewFragment">
|
||||||
|
|
||||||
<GridView
|
<androidx.cardview.widget.CardView
|
||||||
android:id="@+id/approvals_list"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:numColumns="2"
|
android:layout_gravity="center"
|
||||||
android:rowCount="4"
|
android:layout_marginBottom="12dp"
|
||||||
android:stretchMode="columnWidth"
|
app:cardBackgroundColor="@color/colour_nine"
|
||||||
tools:listitem="@layout/approval_list_grid_item" />
|
app:cardCornerRadius="28dp"
|
||||||
|
app:cardElevation="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
</RelativeLayout>
|
<ListView
|
||||||
|
android:id="@+id/approvals_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:divider="@color/colour_three"
|
||||||
|
tools:layout_height="658dp"
|
||||||
|
tools:listitem="@layout/approval_list_item" />
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -5,11 +5,86 @@
|
|||||||
android:id="@+id/main_navigation"
|
android:id="@+id/main_navigation"
|
||||||
app:startDestination="@id/homeAdminFragment">
|
app:startDestination="@id/homeAdminFragment">
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:id="@+id/nav_user_settings"
|
||||||
|
android:name="h_mal.appttude.com.driver.ui.update.UpdateActivity"
|
||||||
|
android:label="fragment_profile"
|
||||||
|
tools:layout="@layout/update_activity" />
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/homeAdminFragment"
|
android:id="@+id/homeAdminFragment"
|
||||||
android:name="h_mal.appttude.com.driver.ui.HomeSuperUserFragment"
|
android:name="h_mal.appttude.com.driver.ui.HomeSuperUserFragment"
|
||||||
android:label="fragment_home"
|
android:label="fragment_home"
|
||||||
tools:layout="@layout/fragment_home_super_user">
|
tools:layout="@layout/fragment_home_super_user">
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_homeAdminFragment_to_userMainFragment"
|
||||||
|
app:destination="@id/userMainFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/userMainFragment"
|
||||||
|
android:name="h_mal.appttude.com.driver.ui.DriverOverviewFragment"
|
||||||
|
android:label="fragment_user_main"
|
||||||
|
tools:layout="@layout/fragment_user_main" >
|
||||||
|
<action
|
||||||
|
android:id="@+id/to_driverLicenseFragment"
|
||||||
|
app:destination="@id/driverLicenseFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/to_driverProfileFragment"
|
||||||
|
app:destination="@id/driverProfileFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/to_privateHireLicenseFragment"
|
||||||
|
app:destination="@id/privateHireLicenseFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/to_insuranceFragment"
|
||||||
|
app:destination="@id/insuranceFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/to_logbookFragment"
|
||||||
|
app:destination="@id/logbookFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/to_motFragment"
|
||||||
|
app:destination="@id/motFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/to_privateHireVehicleFragment"
|
||||||
|
app:destination="@id/privateHireVehicleFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/to_vehicleProfileFragment"
|
||||||
|
app:destination="@id/vehicleProfileFragment" />
|
||||||
|
</fragment>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/driverLicenseFragment"
|
||||||
|
android:name="h_mal.appttude.com.driver.ui.driverprofile.DriverLicenseFragment"
|
||||||
|
android:label="DriverLicenseFragment" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/driverProfileFragment"
|
||||||
|
android:name="h_mal.appttude.com.driver.ui.driverprofile.DriverProfileFragment"
|
||||||
|
android:label="fragment_driver_profile"
|
||||||
|
tools:layout="@layout/fragment_driver_profile" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/privateHireLicenseFragment"
|
||||||
|
android:name="h_mal.appttude.com.driver.ui.driverprofile.PrivateHireLicenseFragment"
|
||||||
|
android:label="fragment_private_hire_license"
|
||||||
|
tools:layout="@layout/fragment_private_hire_license" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/insuranceFragment"
|
||||||
|
android:name="h_mal.appttude.com.driver.ui.vehicleprofile.InsuranceFragment"
|
||||||
|
android:label="InsuranceFragment" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/logbookFragment"
|
||||||
|
android:name="h_mal.appttude.com.driver.ui.vehicleprofile.LogbookFragment"
|
||||||
|
android:label="fragment_logbook"
|
||||||
|
tools:layout="@layout/fragment_logbook" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/motFragment"
|
||||||
|
android:name="h_mal.appttude.com.driver.ui.vehicleprofile.MotFragment"
|
||||||
|
android:label="MotFragment" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/privateHireVehicleFragment"
|
||||||
|
android:name="h_mal.appttude.com.driver.ui.vehicleprofile.PrivateHireVehicleFragment"
|
||||||
|
android:label="fragment_private_hire_vehicle"
|
||||||
|
tools:layout="@layout/fragment_private_hire_vehicle" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/vehicleProfileFragment"
|
||||||
|
android:name="h_mal.appttude.com.driver.ui.vehicleprofile.VehicleProfileFragment"
|
||||||
|
android:label="fragment_vehicle_setup"
|
||||||
|
tools:layout="@layout/fragment_vehicle_setup" />
|
||||||
|
|
||||||
</navigation>
|
</navigation>
|
||||||
3
app/src/admin/res/values/strings.xml
Normal file
3
app/src/admin/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">Driver Admin</string>
|
||||||
|
</resources>
|
||||||
@@ -1,5 +1,15 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<network-security-config>
|
<network-security-config>
|
||||||
|
<base-config cleartextTrafficPermitted="false">
|
||||||
|
<trust-anchors>
|
||||||
|
<certificates src="system" />
|
||||||
|
</trust-anchors>
|
||||||
|
</base-config>
|
||||||
|
<debug-overrides>
|
||||||
|
<trust-anchors>
|
||||||
|
<certificates src="user" />
|
||||||
|
</trust-anchors>
|
||||||
|
</debug-overrides>
|
||||||
<domain-config cleartextTrafficPermitted="true">
|
<domain-config cleartextTrafficPermitted="true">
|
||||||
<domain includeSubdomains="true">10.0.2.2</domain>
|
<domain includeSubdomains="true">10.0.2.2</domain>
|
||||||
</domain-config>
|
</domain-config>
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
package="h_mal.appttude.com.driver">
|
|
||||||
|
|
||||||
<application
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
|
||||||
android:roundIcon="@mipmap/ic_launcher_round">
|
|
||||||
|
|
||||||
</application>
|
|
||||||
|
|
||||||
</manifest>
|
|
||||||
@@ -5,12 +5,14 @@ import androidx.lifecycle.ViewModelProvider
|
|||||||
import h_mal.appttude.com.driver.data.FirebaseAuthSource
|
import h_mal.appttude.com.driver.data.FirebaseAuthSource
|
||||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||||
|
import h_mal.appttude.com.driver.data.prefs.PreferenceProvider
|
||||||
import h_mal.appttude.com.driver.viewmodels.*
|
import h_mal.appttude.com.driver.viewmodels.*
|
||||||
|
|
||||||
class ApplicationViewModelFactory(
|
class ApplicationViewModelFactory(
|
||||||
private val auth: FirebaseAuthSource,
|
private val auth: FirebaseAuthSource,
|
||||||
private val database: FirebaseDatabaseSource,
|
private val database: FirebaseDatabaseSource,
|
||||||
private val storage: FirebaseStorageSource
|
private val storage: FirebaseStorageSource,
|
||||||
|
private val preferences: PreferenceProvider
|
||||||
) : ViewModelProvider.Factory {
|
) : ViewModelProvider.Factory {
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@@ -23,6 +25,11 @@ class ApplicationViewModelFactory(
|
|||||||
auth,
|
auth,
|
||||||
storage
|
storage
|
||||||
)
|
)
|
||||||
|
isAssignableFrom(RoleViewModel::class.java) -> RoleViewModel(
|
||||||
|
auth,
|
||||||
|
database,
|
||||||
|
storage
|
||||||
|
)
|
||||||
isAssignableFrom(DriverLicenseViewModel::class.java) -> DriverLicenseViewModel(
|
isAssignableFrom(DriverLicenseViewModel::class.java) -> DriverLicenseViewModel(
|
||||||
auth,
|
auth,
|
||||||
database,
|
database,
|
||||||
@@ -59,11 +66,6 @@ class ApplicationViewModelFactory(
|
|||||||
database,
|
database,
|
||||||
storage
|
storage
|
||||||
)
|
)
|
||||||
isAssignableFrom(RoleViewModel::class.java) -> RoleViewModel(
|
|
||||||
auth,
|
|
||||||
database,
|
|
||||||
storage
|
|
||||||
)
|
|
||||||
else -> throw IllegalArgumentException("Unknown ViewModel class")
|
else -> throw IllegalArgumentException("Unknown ViewModel class")
|
||||||
} as T
|
} as T
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,7 @@ class DriverLicenseViewModel(
|
|||||||
override val storageRef: StorageReference = storage.driversLicenseStorageRef(uid)
|
override val storageRef: StorageReference = storage.driversLicenseStorageRef(uid)
|
||||||
override val objectName: String = "drivers license"
|
override val objectName: String = "drivers license"
|
||||||
|
|
||||||
override fun getDataFromDatabase() = getDataClass<DriversLicense>()
|
override fun getDataFromDatabase() = retrieveDataFromDatabase<DriversLicense>()
|
||||||
|
|
||||||
override fun setDataInDatabase(data: DriversLicense, localImageUri: Uri?) = io {
|
override fun setDataInDatabase(data: DriversLicense, localImageUri: Uri?) = io {
|
||||||
doTryOperation("Failed to upload $objectName") {
|
doTryOperation("Failed to upload $objectName") {
|
||||||
@@ -19,8 +19,7 @@ class DriverProfileViewModel(
|
|||||||
override val databaseRef: DatabaseReference = database.getDriverDetailsRef(uid)
|
override val databaseRef: DatabaseReference = database.getDriverDetailsRef(uid)
|
||||||
override val storageRef: StorageReference = storage.profileImageStorageRef(uid)
|
override val storageRef: StorageReference = storage.profileImageStorageRef(uid)
|
||||||
override val objectName: String = "drivers profile"
|
override val objectName: String = "drivers profile"
|
||||||
|
override fun getDataFromDatabase() = retrieveDataFromDatabase<DriverProfile>()
|
||||||
override fun getDataFromDatabase() = getDataClass<DriverProfile>()
|
|
||||||
|
|
||||||
override fun setDataInDatabase(data: DriverProfile, localImageUri: Uri?) = io {
|
override fun setDataInDatabase(data: DriverProfile, localImageUri: Uri?) = io {
|
||||||
doTryOperation("Failed to upload $objectName") {
|
doTryOperation("Failed to upload $objectName") {
|
||||||
@@ -20,7 +20,7 @@ class InsuranceViewModel(
|
|||||||
override val storageRef: StorageReference = storage.insuranceStorageRef(uid)
|
override val storageRef: StorageReference = storage.insuranceStorageRef(uid)
|
||||||
override val objectName: String = "insurance"
|
override val objectName: String = "insurance"
|
||||||
|
|
||||||
override fun getDataFromDatabase() = getDataClass<Insurance>()
|
override fun getDataFromDatabase() = retrieveDataFromDatabase<Insurance>()
|
||||||
|
|
||||||
override fun setDataInDatabase(data: Insurance, localImageUris: List<Uri?>?) = io {
|
override fun setDataInDatabase(data: Insurance, localImageUris: List<Uri?>?) = io {
|
||||||
doTryOperation("Failed to upload $objectName") {
|
doTryOperation("Failed to upload $objectName") {
|
||||||
@@ -20,7 +20,7 @@ class LogbookViewModel(
|
|||||||
override val storageRef: StorageReference = storage.logBookStorageRef(uid)
|
override val storageRef: StorageReference = storage.logBookStorageRef(uid)
|
||||||
override val objectName: String = "Log book"
|
override val objectName: String = "Log book"
|
||||||
|
|
||||||
override fun getDataFromDatabase() = getDataClass<Logbook>()
|
override fun getDataFromDatabase() = retrieveDataFromDatabase<Logbook>()
|
||||||
|
|
||||||
override fun setDataInDatabase(data: Logbook, localImageUri: Uri?) = io {
|
override fun setDataInDatabase(data: Logbook, localImageUri: Uri?) = io {
|
||||||
doTryOperation("Failed to upload $objectName") {
|
doTryOperation("Failed to upload $objectName") {
|
||||||
@@ -20,7 +20,7 @@ class MotViewModel(
|
|||||||
override val storageRef: StorageReference? = storage.motStorageRef(uid)
|
override val storageRef: StorageReference? = storage.motStorageRef(uid)
|
||||||
override val objectName: String = "vehicle profile"
|
override val objectName: String = "vehicle profile"
|
||||||
|
|
||||||
override fun getDataFromDatabase() = getDataClass<Mot>()
|
override fun getDataFromDatabase() = retrieveDataFromDatabase<Mot>()
|
||||||
|
|
||||||
override fun setDataInDatabase(data: Mot, localImageUri: Uri?) = io {
|
override fun setDataInDatabase(data: Mot, localImageUri: Uri?) = io {
|
||||||
doTryOperation("Failed to upload $objectName") {
|
doTryOperation("Failed to upload $objectName") {
|
||||||
@@ -20,7 +20,7 @@ class PrivateHireLicenseViewModel(
|
|||||||
override val storageRef: StorageReference = storage.privateHireStorageRef(uid)
|
override val storageRef: StorageReference = storage.privateHireStorageRef(uid)
|
||||||
override val objectName: String = "private hire license"
|
override val objectName: String = "private hire license"
|
||||||
|
|
||||||
override fun getDataFromDatabase() = getDataClass<PrivateHireLicense>()
|
override fun getDataFromDatabase() = retrieveDataFromDatabase<PrivateHireLicense>()
|
||||||
|
|
||||||
override fun setDataInDatabase(data: PrivateHireLicense, localImageUri: Uri?) = io {
|
override fun setDataInDatabase(data: PrivateHireLicense, localImageUri: Uri?) = io {
|
||||||
doTryOperation("Failed to upload private hire license") {
|
doTryOperation("Failed to upload private hire license") {
|
||||||
@@ -20,7 +20,7 @@ class PrivateHireVehicleViewModel(
|
|||||||
override val storageRef: StorageReference = storage.privateHireVehicleStorageRef(uid)
|
override val storageRef: StorageReference = storage.privateHireVehicleStorageRef(uid)
|
||||||
override val objectName: String = "private hire vehicle license"
|
override val objectName: String = "private hire vehicle license"
|
||||||
|
|
||||||
override fun getDataFromDatabase() = getDataClass<PrivateHireVehicle>()
|
override fun getDataFromDatabase() = retrieveDataFromDatabase<PrivateHireVehicle>()
|
||||||
|
|
||||||
override fun setDataInDatabase(data: PrivateHireVehicle, localImageUri: Uri?) = io {
|
override fun setDataInDatabase(data: PrivateHireVehicle, localImageUri: Uri?) = io {
|
||||||
doTryOperation("Failed to upload $objectName") {
|
doTryOperation("Failed to upload $objectName") {
|
||||||
@@ -19,7 +19,7 @@ class VehicleProfileViewModel(
|
|||||||
override val storageRef: StorageReference? = null
|
override val storageRef: StorageReference? = null
|
||||||
override val objectName: String = "vehicle profile"
|
override val objectName: String = "vehicle profile"
|
||||||
|
|
||||||
override fun getDataFromDatabase() = getDataClass<VehicleProfile>()
|
override fun getDataFromDatabase() = retrieveDataFromDatabase<VehicleProfile>()
|
||||||
|
|
||||||
override fun setDataInDatabase(data: VehicleProfile) {
|
override fun setDataInDatabase(data: VehicleProfile) {
|
||||||
io {
|
io {
|
||||||
46
app/src/driver/res/layout/activity_main.xml
Normal file
46
app/src/driver/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/drawer_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
|
tools:openDrawer="start">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/app_bar_layout"
|
||||||
|
layout="@layout/app_bar_main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<com.google.android.material.navigation.NavigationView
|
||||||
|
android:id="@+id/nav_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="start"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
|
app:itemTextColor="@android:color/white"
|
||||||
|
app:headerLayout="@layout/nav_header_main"
|
||||||
|
app:menu="@menu/activity_main_drawer">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/logout"
|
||||||
|
style="@style/headerStyle"
|
||||||
|
android:background="@color/colour_nine"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/logout"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</LinearLayout>
|
||||||
|
</com.google.android.material.navigation.NavigationView>
|
||||||
|
|
||||||
|
</androidx.drawerlayout.widget.DrawerLayout>
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<!-- TODO: Remove or change this placeholder text -->
|
<string name="app_name">Driver Choice cars</string>
|
||||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="h_mal.appttude.com.driver.application.DriverApplication"
|
android:name=".application.DriverApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
@@ -13,8 +13,7 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity
|
<activity
|
||||||
android:name="h_mal.appttude.com.driver.ui.user.LoginActivity"
|
android:name=".ui.user.LoginActivity"
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/AppTheme.NoActionBar.User"
|
android:theme="@style/AppTheme.NoActionBar.User"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@@ -25,17 +24,16 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name="h_mal.appttude.com.driver.ui.MainActivity"
|
android:name=".ui.MainActivity"
|
||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/AppTheme.NoActionBar" />
|
android:theme="@style/AppTheme.NoActionBar" />
|
||||||
<activity
|
<activity
|
||||||
android:name="h_mal.appttude.com.driver.ui.update.UpdateActivity"
|
android:name=".ui.update.UpdateActivity"
|
||||||
android:theme="@style/AppTheme.NoActionBar.Update" />
|
android:theme="@style/AppTheme.NoActionBar.Update" />
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="h_mal.appttude.com.driver"
|
android:authorities="${applicationId}.contentprovider"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:grantUriPermissions="true">
|
android:grantUriPermissions="true">
|
||||||
<meta-data
|
<meta-data
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.app.Application
|
|||||||
import h_mal.appttude.com.driver.data.FirebaseAuthSource
|
import h_mal.appttude.com.driver.data.FirebaseAuthSource
|
||||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||||
|
import h_mal.appttude.com.driver.data.prefs.PreferenceProvider
|
||||||
import org.kodein.di.Kodein
|
import org.kodein.di.Kodein
|
||||||
import org.kodein.di.KodeinAware
|
import org.kodein.di.KodeinAware
|
||||||
import org.kodein.di.android.x.androidXModule
|
import org.kodein.di.android.x.androidXModule
|
||||||
@@ -20,6 +21,7 @@ class DriverApplication : Application(), KodeinAware {
|
|||||||
bind() from singleton { FirebaseAuthSource() }
|
bind() from singleton { FirebaseAuthSource() }
|
||||||
bind() from singleton { FirebaseDatabaseSource() }
|
bind() from singleton { FirebaseDatabaseSource() }
|
||||||
bind() from singleton { FirebaseStorageSource() }
|
bind() from singleton { FirebaseStorageSource() }
|
||||||
bind() from provider { ApplicationViewModelFactory(instance(), instance(), instance()) }
|
bind() from singleton { PreferenceProvider(this@DriverApplication) }
|
||||||
|
bind() from provider { ApplicationViewModelFactory(instance(), instance(), instance(), instance()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,6 @@ package h_mal.appttude.com.driver.base
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup.LayoutParams
|
import android.view.ViewGroup.LayoutParams
|
||||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
@@ -16,12 +15,11 @@ import h_mal.appttude.com.driver.R
|
|||||||
import h_mal.appttude.com.driver.application.ApplicationViewModelFactory
|
import h_mal.appttude.com.driver.application.ApplicationViewModelFactory
|
||||||
import h_mal.appttude.com.driver.data.ViewState
|
import h_mal.appttude.com.driver.data.ViewState
|
||||||
import h_mal.appttude.com.driver.utils.*
|
import h_mal.appttude.com.driver.utils.*
|
||||||
|
import h_mal.appttude.com.driver.utils.GenericsHelper.getGenericClassAt
|
||||||
|
import h_mal.appttude.com.driver.utils.GenericsHelper.inflateBindingByType
|
||||||
import org.kodein.di.KodeinAware
|
import org.kodein.di.KodeinAware
|
||||||
import org.kodein.di.android.kodein
|
import org.kodein.di.android.kodein
|
||||||
import org.kodein.di.generic.instance
|
import org.kodein.di.generic.instance
|
||||||
import java.lang.reflect.ParameterizedType
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
|
|
||||||
abstract class BaseActivity<V : BaseViewModel, VB : ViewBinding> : AppCompatActivity(), KodeinAware {
|
abstract class BaseActivity<V : BaseViewModel, VB : ViewBinding> : AppCompatActivity(), KodeinAware {
|
||||||
// The Idling Resource which will be null in production.
|
// The Idling Resource which will be null in production.
|
||||||
@@ -47,34 +45,12 @@ abstract class BaseActivity<V : BaseViewModel, VB : ViewBinding> : AppCompatActi
|
|||||||
{ defaultViewModelCreationExtras }
|
{ defaultViewModelCreationExtras }
|
||||||
)
|
)
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
fun <CLASS : Any> Any.getGenericClassAt(position: Int): KClass<CLASS> =
|
|
||||||
((javaClass.genericSuperclass as? ParameterizedType)
|
|
||||||
?.actualTypeArguments?.getOrNull(position) as? Class<CLASS>)
|
|
||||||
?.kotlin
|
|
||||||
?: throw IllegalStateException("Can not find class from generic argument")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a view binding out of the the generic [VB]
|
|
||||||
*/
|
|
||||||
private fun inflateBindingByType(
|
|
||||||
genericClassAt: KClass<VB>
|
|
||||||
): VB = try {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
genericClassAt.java.methods.first { viewBinding ->
|
|
||||||
viewBinding.parameterTypes.size == 1
|
|
||||||
&& viewBinding.parameterTypes.getOrNull(0) == LayoutInflater::class.java
|
|
||||||
}.invoke(null, layoutInflater) as VB
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
throw IllegalStateException("Can not inflate binding from generic")
|
|
||||||
}
|
|
||||||
|
|
||||||
private var loading: Boolean = false
|
private var loading: Boolean = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
configureObserver()
|
configureObserver()
|
||||||
_binding = inflateBindingByType(getGenericClassAt(1))
|
_binding = inflateBindingByType(getGenericClassAt(1), layoutInflater)
|
||||||
setContentView(requireNotNull(_binding).root)
|
setContentView(requireNotNull(_binding).root)
|
||||||
setupView(binding)
|
setupView(binding)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package h_mal.appttude.com.driver.base
|
||||||
|
|
||||||
|
import android.net.ConnectivityManager
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
import com.firebase.ui.database.FirebaseRecyclerAdapter
|
||||||
|
import com.firebase.ui.database.FirebaseRecyclerOptions
|
||||||
|
import h_mal.appttude.com.driver.utils.GenericsHelper.getGenericClassAt
|
||||||
|
import h_mal.appttude.com.driver.utils.GenericsHelper.inflateBindingByType
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
|
|
||||||
|
open class BaseFirebaseAdapter<T: Any, VB : ViewBinding>(options: FirebaseRecyclerOptions<T>, private val layoutInflater: LayoutInflater):
|
||||||
|
FirebaseRecyclerAdapter<T, CustomViewHolder<VB>>(options) {
|
||||||
|
|
||||||
|
private val connectivityManager = layoutInflater.context.getSystemService(ConnectivityManager::class.java) as ConnectivityManager
|
||||||
|
|
||||||
|
private var _binding: VB? = null
|
||||||
|
val binding: VB
|
||||||
|
get() = _binding ?: error("Must only access binding while fragment is attached.")
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder<VB> {
|
||||||
|
_binding = inflateBindingByType(getGenericClassAt(1), layoutInflater)
|
||||||
|
val lp = RecyclerView.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
|
)
|
||||||
|
binding.root.layoutParams = lp
|
||||||
|
return CustomViewHolder(requireNotNull(_binding))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: CustomViewHolder<VB>, position: Int, model: T) { }
|
||||||
|
|
||||||
|
override fun getItemId(position: Int): Long {
|
||||||
|
return snapshots.getSnapshot(position).key?.toByteArray()
|
||||||
|
?.let { ByteBuffer.wrap(it).long } ?: super.getItemId(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getKeyAtPosition(position: Int) = snapshots.getSnapshot(position).key
|
||||||
|
|
||||||
|
override fun startListening() {
|
||||||
|
super.startListening()
|
||||||
|
// check if network is connected
|
||||||
|
if (connectivityManager.activeNetwork == null) {
|
||||||
|
connectionLost()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun connectionLost() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomViewHolder<VB : ViewBinding>(val viewBinding: VB): ViewHolder(viewBinding.root)
|
||||||
@@ -1,29 +1,27 @@
|
|||||||
package h_mal.appttude.com.driver.base
|
package h_mal.appttude.com.driver.base
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.activity.result.contract.ActivityResultContract
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.createViewModelLazy
|
import androidx.fragment.app.createViewModelLazy
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import h_mal.appttude.com.driver.application.ApplicationViewModelFactory
|
import h_mal.appttude.com.driver.application.ApplicationViewModelFactory
|
||||||
import h_mal.appttude.com.driver.data.ViewState
|
import h_mal.appttude.com.driver.data.ViewState
|
||||||
|
import h_mal.appttude.com.driver.utils.GenericsHelper.getGenericClassAt
|
||||||
|
import h_mal.appttude.com.driver.utils.GenericsHelper.inflateBindingByType
|
||||||
import h_mal.appttude.com.driver.utils.PermissionsUtils
|
import h_mal.appttude.com.driver.utils.PermissionsUtils
|
||||||
import org.kodein.di.KodeinAware
|
import org.kodein.di.KodeinAware
|
||||||
import org.kodein.di.android.x.kodein
|
import org.kodein.di.android.x.kodein
|
||||||
import org.kodein.di.generic.instance
|
import org.kodein.di.generic.instance
|
||||||
import java.lang.reflect.ParameterizedType
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
const val IMAGE_SELECT_REQUEST_CODE = 401
|
abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding> : Fragment(), KodeinAware {
|
||||||
|
|
||||||
abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding>(
|
|
||||||
) : Fragment(), KodeinAware {
|
|
||||||
|
|
||||||
private var _binding: VB? = null
|
private var _binding: VB? = null
|
||||||
private val binding: VB
|
private val binding: VB
|
||||||
@@ -31,7 +29,12 @@ abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding>(
|
|||||||
|
|
||||||
var mActivity: BaseActivity<V, *>? = null
|
var mActivity: BaseActivity<V, *>? = null
|
||||||
|
|
||||||
|
override val kodein by kodein()
|
||||||
|
private val factory by instance<ApplicationViewModelFactory>()
|
||||||
|
|
||||||
val viewModel: V by getFragmentViewModel()
|
val viewModel: V by getFragmentViewModel()
|
||||||
|
private fun getFragmentViewModel(): Lazy<V> =
|
||||||
|
createViewModelLazy(getGenericClassAt(0), { viewModelStore }, factoryProducer = { factory })
|
||||||
|
|
||||||
private var multipleImage: Boolean = false
|
private var multipleImage: Boolean = false
|
||||||
|
|
||||||
@@ -39,33 +42,6 @@ abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding>(
|
|||||||
multipleImage = true
|
multipleImage = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override val kodein by kodein()
|
|
||||||
val factory by instance<ApplicationViewModelFactory>()
|
|
||||||
|
|
||||||
fun getFragmentViewModel(): Lazy<V> =
|
|
||||||
createViewModelLazy(getGenericClassAt(0), { viewModelStore }, factoryProducer = { factory })
|
|
||||||
|
|
||||||
fun LayoutInflater.inflateBindingByType(
|
|
||||||
container: ViewGroup?,
|
|
||||||
genericClassAt: KClass<VB>
|
|
||||||
): VB = try {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
genericClassAt.java.methods.first { inflateFun ->
|
|
||||||
inflateFun.parameterTypes.size == 3
|
|
||||||
&& inflateFun.parameterTypes.getOrNull(0) == LayoutInflater::class.java
|
|
||||||
&& inflateFun.parameterTypes.getOrNull(1) == ViewGroup::class.java
|
|
||||||
&& inflateFun.parameterTypes.getOrNull(2) == Boolean::class.java
|
|
||||||
}.invoke(null, this, container, false) as VB
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
throw IllegalStateException("Can not inflate binding from generic")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
fun <CLASS : Any> Any.getGenericClassAt(position: Int): KClass<CLASS> =
|
|
||||||
((javaClass.genericSuperclass as? ParameterizedType)
|
|
||||||
?.actualTypeArguments?.getOrNull(position) as? Class<CLASS>)
|
|
||||||
?.kotlin
|
|
||||||
?: throw IllegalStateException("Can not find class from generic argument")
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
@@ -126,25 +102,6 @@ abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
|
||||||
when (requestCode) {
|
|
||||||
IMAGE_SELECT_REQUEST_CODE -> {
|
|
||||||
data?.clipData?.convertToList()?.let { clip ->
|
|
||||||
val list = clip.takeIf { it.size > 10 }?.let {
|
|
||||||
clip.subList(0, 9)
|
|
||||||
} ?: clip
|
|
||||||
onImageGalleryResult(list)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
onImageGalleryResult(data?.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ClipData.convertToList(): List<Uri> = 0.rangeTo(itemCount).map { getItemAt(it).uri }
|
private fun ClipData.convertToList(): List<Uri> = 0.rangeTo(itemCount).map { getItemAt(it).uri }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -180,10 +137,33 @@ abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding>(
|
|||||||
open fun onImageGalleryResult(imageUris: List<Uri>?) {}
|
open fun onImageGalleryResult(imageUris: List<Uri>?) {}
|
||||||
|
|
||||||
fun openGalleryForImage() {
|
fun openGalleryForImage() {
|
||||||
val intent = Intent(Intent.ACTION_PICK)
|
registerForActivityResult(getResultsContract()) { result ->
|
||||||
intent.type = "image/*"
|
@Suppress("UNCHECKED_CAST")
|
||||||
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, multipleImage)
|
when (result) {
|
||||||
startActivityForResult(intent, IMAGE_SELECT_REQUEST_CODE)
|
is Uri -> onImageGalleryResult(result)
|
||||||
|
is List<*> -> onImageGalleryResult(result as List<Uri>)
|
||||||
|
}
|
||||||
|
}.launch(multipleImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getResultsContract(): ActivityResultContract<Boolean, Any?> {
|
||||||
|
return object : ActivityResultContract<Boolean, Any?>() {
|
||||||
|
override fun createIntent(context: Context, input: Boolean): Intent {
|
||||||
|
return Intent(Intent.ACTION_PICK).apply {
|
||||||
|
type = "image/*"
|
||||||
|
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun parseResult(resultCode: Int, intent: Intent?): Any? {
|
||||||
|
intent?.clipData?.convertToList()?.let { clip ->
|
||||||
|
val list = clip.takeIf { it.size > 10 }?.let {
|
||||||
|
clip.subList(0, 9)
|
||||||
|
} ?: clip
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
return intent?.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -29,14 +29,11 @@ abstract class BaseViewModel : ViewModel() {
|
|||||||
operation()
|
operation()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
e.message?.let {
|
|
||||||
onError(it)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defaultErrorMessage?.let {
|
defaultErrorMessage?.let {
|
||||||
onError(it)
|
onError(it)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
onError((e.message ?: "Operation failed!!"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,7 @@ import kotlinx.coroutines.async
|
|||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
|
|
||||||
abstract class DataSubmissionBaseViewModel<T : Any>(
|
abstract class DataSubmissionBaseViewModel<T : Any>(
|
||||||
auth: FirebaseAuthentication,
|
auth: FirebaseAuthentication,
|
||||||
private val database: FirebaseDatabaseSource,
|
private val database: FirebaseDatabaseSource,
|
||||||
@@ -32,7 +33,7 @@ abstract class DataSubmissionBaseViewModel<T : Any>(
|
|||||||
open fun setDataInDatabase(data: T, localImageUris: List<Uri?>?): Job = Job()
|
open fun setDataInDatabase(data: T, localImageUris: List<Uri?>?): Job = Job()
|
||||||
open fun setDataInDatabase(data: T) {}
|
open fun setDataInDatabase(data: T) {}
|
||||||
|
|
||||||
inline fun <reified T : Any> getDataClass() = io {
|
inline fun <reified T : Any> retrieveDataFromDatabase() = io {
|
||||||
doTryOperation("Failed to retrieve $objectName") {
|
doTryOperation("Failed to retrieve $objectName") {
|
||||||
val data = databaseRef.getDataFromDatabaseRef<T>()
|
val data = databaseRef.getDataFromDatabaseRef<T>()
|
||||||
onSuccess(data ?: FirebaseCompletion.Default)
|
onSuccess(data ?: FirebaseCompletion.Default)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ const val PRIVATE_HIRE_VEHICLE = "private_hire_vehicle"
|
|||||||
const val VEHICLE_DETAILS = "vehicle_details"
|
const val VEHICLE_DETAILS = "vehicle_details"
|
||||||
const val ARCHIVE = "archive"
|
const val ARCHIVE = "archive"
|
||||||
|
|
||||||
|
@SuppressWarnings("unused|WeakerAccess")
|
||||||
class FirebaseDatabaseSource {
|
class FirebaseDatabaseSource {
|
||||||
private val database = FirebaseDatabase.getInstance()
|
private val database = FirebaseDatabase.getInstance()
|
||||||
|
|
||||||
@@ -35,7 +36,12 @@ class FirebaseDatabaseSource {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUserRef(uid: String) = database.getReference(USER_CONST).child(uid)
|
fun getDatabaseReferenceFromLink(link: String) = database.getReferenceFromUrl(link)
|
||||||
|
|
||||||
|
val users = database.getReference(USER_CONST)
|
||||||
|
|
||||||
|
fun getUsersRef() = database.reference.child(USER_CONST)
|
||||||
|
fun getUserRef(uid: String) = users.child(uid)
|
||||||
fun getUserDetailsRef(uid: String) = getUserRef(uid).child(USER_DETAILS)
|
fun getUserDetailsRef(uid: String) = getUserRef(uid).child(USER_DETAILS)
|
||||||
fun getVehicleRef(uid: String) = getUserRef(uid).child(VEHICLE_PROFILE)
|
fun getVehicleRef(uid: String) = getUserRef(uid).child(VEHICLE_PROFILE)
|
||||||
fun getDriverRef(uid: String) = getUserRef(uid).child(DRIVER_PROFILE)
|
fun getDriverRef(uid: String) = getUserRef(uid).child(DRIVER_PROFILE)
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package h_mal.appttude.com.driver.data.prefs
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared prefs class used for storing conversion name values as pairs
|
||||||
|
* Then retrieving as pairs
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const val SORT_OPTION = "SORT_OPTION"
|
||||||
|
class PreferenceProvider (context: Context) {
|
||||||
|
|
||||||
|
private val appContext = context.applicationContext
|
||||||
|
|
||||||
|
private val preference: SharedPreferences =
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(appContext)
|
||||||
|
|
||||||
|
fun setSortOption(sortLabel: String) {
|
||||||
|
preference.edit()
|
||||||
|
.putString(SORT_OPTION, sortLabel)
|
||||||
|
.apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSortOption(): String? = preference
|
||||||
|
.getString(SORT_OPTION, null)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,13 +1,22 @@
|
|||||||
package h_mal.appttude.com.driver.utils
|
package h_mal.appttude.com.driver.utils
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension function that will execute high order if value is true or do nothing
|
||||||
|
*
|
||||||
|
* @sample #boolean.isTrue{ #Do something when its true }
|
||||||
|
*/
|
||||||
inline fun Boolean.isTrue(block: () -> Unit){
|
inline fun Boolean.isTrue(block: () -> Unit){
|
||||||
if (this) {
|
if (this) {
|
||||||
block()
|
block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T, R> T.isNotNull(block: (T) -> R): R?{
|
/**
|
||||||
|
* Extension function that will execute high order if value is not null or do nothing
|
||||||
|
*
|
||||||
|
* @sample #nullable.isNotNull{i -> i.doSomethingSinceItsNotNull() }
|
||||||
|
*/
|
||||||
|
inline fun <T, R> T?.isNotNull(block: (T) -> R): R?{
|
||||||
return if (this != null) {
|
return if (this != null) {
|
||||||
block(this)
|
block(this)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -43,3 +43,14 @@ suspend inline fun <reified T : Any> DatabaseReference.getDataFromDatabaseRef():
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun <T: Any> DatabaseReference.getDataFromDatabaseRef(clazz : Class<T>): T? {
|
||||||
|
return when (val response: EventResponse = singleValueEvent()) {
|
||||||
|
is EventResponse.Changed -> {
|
||||||
|
response.snapshot.getValue(clazz)
|
||||||
|
}
|
||||||
|
is EventResponse.Cancelled -> {
|
||||||
|
throw response.error.toException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package h_mal.appttude.com.driver.utils
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
import java.lang.reflect.ParameterizedType
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
object GenericsHelper {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
fun <CLASS : Any> Any.getGenericClassAt(position: Int): KClass<CLASS> =
|
||||||
|
((javaClass.genericSuperclass as? ParameterizedType)
|
||||||
|
?.actualTypeArguments?.getOrNull(position) as? Class<CLASS>)
|
||||||
|
?.kotlin
|
||||||
|
?: throw IllegalStateException("Can not find class from generic argument")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a view binding out of the the generic [VB]
|
||||||
|
*
|
||||||
|
* @sample inflateBindingByType(getGenericClassAt(0), layoutInflater)
|
||||||
|
*/
|
||||||
|
fun <VB: ViewBinding> inflateBindingByType(
|
||||||
|
genericClassAt: KClass<VB>,
|
||||||
|
layoutInflater: LayoutInflater
|
||||||
|
): VB = try {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
|
||||||
|
genericClassAt.java.methods.first { viewBinding ->
|
||||||
|
viewBinding.parameterTypes.size == 1
|
||||||
|
&& viewBinding.parameterTypes.getOrNull(0) == LayoutInflater::class.java
|
||||||
|
}.invoke(null, layoutInflater) as VB
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
println ("generic class failed at = $genericClassAt")
|
||||||
|
exception.printStackTrace()
|
||||||
|
throw IllegalStateException("Can not inflate binding from generic")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <VB: ViewBinding> LayoutInflater.inflateBindingByType(
|
||||||
|
container: ViewGroup?,
|
||||||
|
genericClassAt: KClass<VB>
|
||||||
|
): VB = try {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
genericClassAt.java.methods.first { inflateFun ->
|
||||||
|
inflateFun.parameterTypes.size == 3
|
||||||
|
&& inflateFun.parameterTypes.getOrNull(0) == LayoutInflater::class.java
|
||||||
|
&& inflateFun.parameterTypes.getOrNull(1) == ViewGroup::class.java
|
||||||
|
&& inflateFun.parameterTypes.getOrNull(2) == Boolean::class.java
|
||||||
|
}.invoke(null, this, container, false) as VB
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
throw IllegalStateException("Can not inflate binding from generic")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,28 +1,29 @@
|
|||||||
package h_mal.appttude.com.driver.utils
|
package h_mal.appttude.com.driver.utils
|
||||||
|
|
||||||
import android.content.Context
|
import android.os.Bundle
|
||||||
import android.content.Intent
|
import android.os.Parcelable
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.annotation.IdRes
|
import androidx.annotation.IdRes
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
|
|
||||||
const val UPLOAD_NEW = "upload_new"
|
fun View.navigateTo(@IdRes navId: Int, args: Bundle? = null) {
|
||||||
|
Navigation
|
||||||
|
.findNavController(this)
|
||||||
|
.navigate(navId, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Any.toBundle(key: String): Bundle {
|
||||||
|
return Bundle().apply {
|
||||||
|
when (this@toBundle) {
|
||||||
|
is String -> putString(key, this@toBundle)
|
||||||
|
is Int -> putInt(key, this@toBundle)
|
||||||
|
is Boolean -> putBoolean(key, this@toBundle)
|
||||||
|
is Parcelable -> putParcelable(key, this@toBundle)
|
||||||
|
is Double -> putDouble(key, this@toBundle)
|
||||||
|
is Float -> putFloat(key, this@toBundle)
|
||||||
|
}
|
||||||
|
|
||||||
fun navigateToActivity(context: Context, navigationActivity: Navigations) {
|
|
||||||
try {
|
|
||||||
val ourClass: Class<*> =
|
|
||||||
Class.forName("h_mal.appttude.com.driver." + navigationActivity.value)
|
|
||||||
val intent = Intent(context, ourClass)
|
|
||||||
context.startActivity(intent)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun View.navigateTo(@IdRes navId: Int) {
|
|
||||||
Navigation
|
|
||||||
.findNavController(this)
|
|
||||||
.navigate(navId)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class RoleViewModel(
|
|||||||
override val storageRef: StorageReference? = null
|
override val storageRef: StorageReference? = null
|
||||||
override val objectName: String = "role"
|
override val objectName: String = "role"
|
||||||
|
|
||||||
override fun getDataFromDatabase() = getDataClass<String>()
|
override fun getDataFromDatabase() = retrieveDataFromDatabase<String>()
|
||||||
|
|
||||||
override fun setDataInDatabase(data: String) {
|
override fun setDataInDatabase(data: String) {
|
||||||
io {
|
io {
|
||||||
|
|||||||
@@ -18,22 +18,9 @@
|
|||||||
android:layout_marginBottom="24dp"
|
android:layout_marginBottom="24dp"
|
||||||
android:text="@string/not_a_driver_message" />
|
android:text="@string/not_a_driver_message" />
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/request_driver_button"
|
android:id="@+id/request_driver_button"
|
||||||
android:layout_width="match_parent"
|
style="@style/TextButton"
|
||||||
android:layout_height="wrap_content"
|
android:text="@string/request_driver_profile" />
|
||||||
android:backgroundTint="@color/colour_one"
|
|
||||||
android:selectAllOnFocus="true"
|
|
||||||
app:cardCornerRadius="8dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="8dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/request_driver_profile"
|
|
||||||
android:textColor="@android:color/white"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -46,7 +46,8 @@
|
|||||||
tools:src="@drawable/choice_img_round" />
|
tools:src="@drawable/choice_img_round" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout style="@style/text_input_layout">
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
style="@style/text_input_layout">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/names_input"
|
android:id="@+id/names_input"
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
style="@style/parent_constraint_layout"
|
style="@style/parent_constraint_layout"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
tools:context=".ui.vehicleprofile.LogbookFragment">
|
|
||||||
|
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<androidx.cardview.widget.CardView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
style="@style/parent_constraint_layout"
|
style="@style/parent_constraint_layout">
|
||||||
tools:context=".ui.vehicleprofile.PrivateHireVehicleFragment">
|
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<androidx.cardview.widget.CardView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
android:orientation="vertical">
|
||||||
android:orientation="vertical"
|
|
||||||
tools:context=".ui.vehicleprofile.VehicleProfileFragment">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -5,6 +5,6 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/archive"
|
android:id="@+id/archive"
|
||||||
android:icon="@drawable/ic_sort_black_24dp"
|
android:icon="@drawable/ic_sort_black_24dp"
|
||||||
android:title="sort"
|
android:title="@string/sort"
|
||||||
app:showAsAction="ifRoom"></item>
|
app:showAsAction="ifRoom" />
|
||||||
</menu>
|
</menu>
|
||||||
@@ -14,5 +14,6 @@
|
|||||||
<color name="colour_seven">#91ddff</color>
|
<color name="colour_seven">#91ddff</color>
|
||||||
|
|
||||||
<color name="colour_eight">#9958BE3F</color>
|
<color name="colour_eight">#9958BE3F</color>
|
||||||
|
<color name="colour_ten">#604D4A51</color>
|
||||||
<color name="colour_nine">#303030</color>
|
<color name="colour_nine">#303030</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -4,4 +4,5 @@
|
|||||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||||
<dimen name="nav_header_vertical_spacing">8dp</dimen>
|
<dimen name="nav_header_vertical_spacing">8dp</dimen>
|
||||||
<dimen name="nav_header_height">200dp</dimen>
|
<dimen name="nav_header_height">200dp</dimen>
|
||||||
|
<dimen name="status_size">16dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Choice Minicabs</string>
|
|
||||||
<string name="nav_header_title">Driver Name</string>
|
<string name="nav_header_title">Driver Name</string>
|
||||||
<string name="nav_header_subtitle">driver@example.com</string>
|
<string name="nav_header_subtitle">driver@example.com</string>
|
||||||
<string name="nav_header_desc">Navigation header</string>
|
<string name="nav_header_desc">Navigation header</string>
|
||||||
@@ -83,7 +82,7 @@
|
|||||||
<string name="insurance">Insurance</string>
|
<string name="insurance">Insurance</string>
|
||||||
<string name="m_o_t">M.O.T</string>
|
<string name="m_o_t">M.O.T</string>
|
||||||
<string name="log_book">Log book</string>
|
<string name="log_book">Log book</string>
|
||||||
<string name="private_hire_vehicle_license">Private hire Vehicle License</string>
|
<string name="private_hire_vehicle_license">Private Hire Vehicle License</string>
|
||||||
<string name="upload_insurance_documents">Upload Insurance Documents</string>
|
<string name="upload_insurance_documents">Upload Insurance Documents</string>
|
||||||
<string name="insurer">Insurer</string>
|
<string name="insurer">Insurer</string>
|
||||||
<string name="insurance_expiry">Insurance expiry</string>
|
<string name="insurance_expiry">Insurance expiry</string>
|
||||||
@@ -95,4 +94,11 @@
|
|||||||
<string name="request_driver_profile">Request driver profile</string>
|
<string name="request_driver_profile">Request driver profile</string>
|
||||||
<string name="or">OR</string>
|
<string name="or">OR</string>
|
||||||
<string name="floating_action_button">Floating action button</string>
|
<string name="floating_action_button">Floating action button</string>
|
||||||
|
<string name="sort">sort</string>
|
||||||
|
<string name="denied">Approval denied</string>
|
||||||
|
<string name="pending">Pending approval</string>
|
||||||
|
<string name="approved">Approved</string>
|
||||||
|
<string name="not_submitted">Not submitted</string>
|
||||||
|
<string name="empty_view_message">You have no drivers</string>
|
||||||
|
<string name="approval_status">approval status</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user