- Redesigned layouts

- Updates to behaviour

Took 54 hours 51 minutes
This commit is contained in:
2020-09-30 13:41:43 +01:00
parent c476ed556d
commit 1268f29984
111 changed files with 4950 additions and 1411 deletions

View File

@@ -23,7 +23,7 @@
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/content/ic_filter_list_black_24dp.xml" />
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material/icons/materialicons/attach_money/baseline_attach_money_24.xml" />
</map>
</option>
</PersistentState>
@@ -33,8 +33,7 @@
</option>
<option name="values">
<map>
<entry key="color" value="ffffff" />
<entry key="outputName" value="ic_filter_list_black_24dp" />
<entry key="outputName" value="ic_baseline_attach_money_24" />
<entry key="sourceFile" value="C:\Users\h_mal" />
</map>
</option>

3
.idea/dictionaries/h_mal.xml generated Normal file
View File

@@ -0,0 +1,3 @@
<component name="ProjectDictionaryState">
<dictionary name="h_mal" />
</component>

322
.idea/navEditor.xml generated
View File

@@ -3,6 +3,108 @@
<component name="navEditor-manualLayoutAlgorithm2">
<option name="myPositions">
<map>
<entry key="add_shift_navigation.xml">
<value>
<LayoutPositions>
<option name="myPositions">
<map>
<entry key="addEmployerFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="500" />
<option name="y" value="12" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="addShiftFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="12" />
<option name="y" value="54" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="addShift_to_employersFragment">
<value>
<LayoutPositions />
</value>
</entry>
<entry key="addShift_to_tasksFragment">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="addTaskFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="500" />
<option name="y" value="368" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="employersFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="256" />
<option name="y" value="12" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="employers_to_addEmployerFragment">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="tasksFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="256" />
<option name="y" value="368" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="action_tasksFragment_to_addTaskFragment">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="auth_navigation.xml">
<value>
<LayoutPositions>
@@ -173,6 +275,226 @@
</LayoutPositions>
</value>
</entry>
<entry key="main_navigation.xml">
<value>
<LayoutPositions>
<option name="myPositions">
<map>
<entry key="addNewShiftActivity">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="258" />
<option name="y" value="381" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="addShiftActivity">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="241" />
<option name="y" value="-350" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="backToLogin">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="613" />
<option name="y" value="-608" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="changeEmailFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="868" />
<option name="y" value="-462" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="changeNameFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="861" />
<option name="y" value="-79" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="changePasswordFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="1048" />
<option name="y" value="-280" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="nav_settings">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="618" />
<option name="y" value="-264" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="mainTo_loginHomeFragment">
<value>
<LayoutPositions />
</value>
</entry>
<entry key="to_changeEmailFragment">
<value>
<LayoutPositions />
</value>
</entry>
<entry key="to_changeNameFragment">
<value>
<LayoutPositions />
</value>
</entry>
<entry key="to_changePasswordFragment">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="navigation_home">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="12" />
<option name="y" value="12" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="navigation_list">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="243" />
<option name="y" value="14" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="list_to_addShiftActivity">
<value>
<LayoutPositions />
</value>
</entry>
<entry key="list_to_shiftOverviewFragment">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="navigation_tools">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="12" />
<option name="y" value="368" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="action_navigation_tools_to_addShiftActivity">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="shiftOverviewFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="551" />
<option name="y" value="151" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="shiftOverview_to_addShiftActivity">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="shift_navigation.xml">
<value>
<LayoutPositions>
<option name="myPositions">
<map>
<entry key="addShiftFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="12" />
<option name="y" value="12" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
</map>
</option>
</component>

View File

@@ -8,6 +8,10 @@ apply plugin: 'com.google.gms.google-services'
// Android navigation
apply plugin: 'androidx.navigation.safeargs'
apply plugin: 'com.google.firebase.crashlytics'
repositories {
mavenCentral()
}
android {
compileSdkVersion 29
@@ -55,24 +59,39 @@ dependencies {
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.exifinterface:exifinterface:1.2.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
// Android navigation
def nav_version = "2.3.0"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
// Feature module Support
implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
implementation 'androidx.preference:preference:1.1.1'
// Testing
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// Crashlytics
implementation 'com.google.firebase:firebase-crashlytics:17.1.1'
implementation 'com.google.firebase:firebase-analytics:17.4.4'
// Gson
implementation 'com.google.code.gson:gson:2.3.1'
implementation 'com.google.code.gson:gson:2.8.5'
// Google Play Services
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'com.google.android.gms:play-services-auth:18.1.0'
// Firebase
implementation 'com.google.firebase:firebase-core:16.0.1'
implementation 'com.google.firebase:firebase-auth:16.2.1'
implementation 'com.google.firebase:firebase-storage:16.0.1'
implementation 'com.google.firebase:firebase-database:16.0.1'
implementation 'com.google.firebase:firebase-core:17.4.4'
implementation 'com.google.firebase:firebase-auth:19.3.2'
implementation 'com.google.firebase:firebase-storage:19.1.1'
implementation 'com.google.firebase:firebase-database:19.3.1'
implementation 'com.firebaseui:firebase-ui-database:1.1.1'
implementation 'com.google.firebase:firebase-functions:16.2.0'
implementation 'com.google.firebase:firebase-functions:19.0.2'
implementation 'com.google.firebase:firebase-firestore-ktx:21.6.0'
/* coroutines support for firebase operations */
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.1.1'
//Picasso - load images
implementation 'com.squareup.picasso:picasso:2.71828'
// Zoomable Image view
@@ -85,8 +104,3 @@ dependencies {
implementation "com.github.SUPERCILEX.poi-android:poi:3.17"
}
apply plugin: 'com.google.gms.google-services'
repositories {
mavenCentral()
}

View File

@@ -1,13 +1,14 @@
package com.appttude.h_mal.days_left;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
/**
* Instrumented test, which will execute on an Android device.

View File

@@ -1,43 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.appttude.h_mal.days_left">
<!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:name=".application.AppClass"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name=".application.AppClass"
android:theme="@style/AppTheme.NoActionBar">
<activity android:name=".ui.splashScreen.SplashFragment"
<activity android:name=".ui.BasicActivity"></activity>
<!-- Splash Screen -->
<activity
android:name=".ui.splashScreen.SplashFragment"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</activity> <!-- Login Screen -->
<activity
android:name="com.appttude.h_mal.days_left.ui.login.FullscreenActivity"
android:name=".ui.login.FullscreenActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name"/>
<activity android:name=".AddItemActivity"/>
<activity android:name=".ChangeUserDetailsActivity" />
<activity android:name=".AddShiftActivity" />
android:label="@string/app_name" /> <!-- Main Screen -->
<activity
android:name=".ui.main.MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name" />
<activity android:name=".ui.addShift.AddNewShiftActivity" />
<activity android:name=".ui.addShift.AddShiftActivity" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
@@ -45,7 +46,7 @@
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
android:resource="@xml/provider_paths" />
</provider>
</application>

View File

@@ -5,70 +5,76 @@ import android.view.View
import com.appttude.h_mal.days_left.models.ShiftObject
import com.firebase.ui.database.FirebaseListAdapter
import com.google.firebase.database.Query
import kotlinx.android.synthetic.main.list_item.view.*
class FireAdapter(activity: Activity?, modelClass: Class<ShiftObject>?, modelLayout: Int, ref: Query?) :
class FireAdapter(
activity: Activity?,
modelClass: Class<ShiftObject>?,
modelLayout: Int,
ref: Query?) :
FirebaseListAdapter<ShiftObject>(activity, modelClass, modelLayout, ref) {
override fun populateView(v: View?, model: ShiftObject?, position: Int) {
v?.farm_name?.text = model?.abnObject?.abn
v?.date?.text = model?.shiftDate
v?.task_name?.text = model?.taskObject?.task
v?.type?.text = model?.taskObject?.workType
val locationString:String = model?.abnObject?.state + " - " + model?.abnObject?.postCode
v?.location?.text = locationString
v?.farm_name?.text = model?.abnObject?.companyName
var s = model?.taskObject?.workType + " - $" + model?.taskObject?.rate + "/"
if (model?.taskObject?.workType == FirebaseClass.HOURLY){
s = "$s Hour"
v?.time_holder?.visibility = View.VISIBLE
v?.units_holder?.visibility = View.GONE
val time = model.timeObject?.timeIn + " - " + model.timeObject!!.timeOut
v?.time?.text = time
model.timeObject!!.breakEpoch.let { mins ->
val breakHolder = v?.break_holder
if (mins > 0){
breakHolder?.visibility = View.VISIBLE
v?.break_time?.text = getBreakTimeString(model.timeObject!!.breakEpoch)
}else{
breakHolder?.visibility = View.GONE
}
}
}else{
s = "$s Unit"
v?.time_holder?.visibility = View.GONE
v?.units_holder?.visibility = View.VISIBLE
v?.units?.text = model?.unitsCount.toString()
}
v?.type?.text = s
// v?.farm_name?.text = model?.abnObject?.abn
// v?.date?.text = model?.shiftDate
// v?.task_name?.text = model?.taskObject?.task
// v?.type?.text = model?.taskObject?.workType
// val locationString:String = model?.abnObject?.state + " - " + model?.abnObject?.postCode
// v?.location?.text = locationString
//
// v?.farm_name?.text = model?.abnObject?.companyName
//
// var s = model?.taskObject?.workType + " - $" + model?.taskObject?.rate + "/"
//
// if (model?.taskObject?.workType == FirebaseClass.HOURLY){
// s = "$s Hour"
// v?.container_three?.visibility = View.VISIBLE
// v?.container_five?.visibility = View.GONE
//
// val time = model.timeObject?.timeIn + " - " + model.timeObject!!.timeOut
// v?.time?.text = time
//
// model.timeObject!!.breakEpoch.let { mins ->
// val breakHolder = v?.container_four
// if (mins > 0){
// breakHolder?.visibility = View.VISIBLE
// v?.break_time?.text = getBreakTimeString(model.timeObject!!.breakEpoch)
// }else{
// breakHolder?.visibility = View.GONE
// }
// }
// }else{
// s = "$s Unit"
// v?.container_three?.visibility = View.GONE
// v?.container_five?.visibility = View.VISIBLE
//
// v?.units?.text = model?.unitsCount.toString()
// }
//
// v?.type?.text = s
}
private fun getBreakTimeString(breakMins: Int): String {
val hoursFloat = (breakMins / 60).toFloat()
val hoursInt = Math.floor(hoursFloat.toDouble()).toInt()
val minsInt = breakMins - hoursInt * 60
var s = ""
if (hoursInt > 0) {
s = "$hoursInt h "
}
// private fun getBreakTimeString(breakMins: Int): String {
// val hoursFloat = (breakMins / 60).toFloat()
//
// val hoursInt = Math.floor(hoursFloat.toDouble()).toInt()
// val minsInt = breakMins - hoursInt * 60
//
// var s = ""
// if (hoursInt > 0) {
// s = "$hoursInt h "
// }
//
// if (minsInt > 0) {
// s = "$s$minsInt m"
// }
//
// return s
// }
//
// fun getId(i: Int): String? {
// return getRef(i).key
// }
if (minsInt > 0) {
s = "$s$minsInt m"
}
return s
}
fun getId(i: Int): String? {
return getRef(i).key
}
}

View File

@@ -1,47 +0,0 @@
package com.appttude.h_mal.days_left
import android.util.Log
import androidx.lifecycle.ViewModel
import com.appttude.h_mal.days_left.data.firebase.FirebaseFunctionsSource
import com.appttude.h_mal.days_left.models.AbnObject
import com.appttude.h_mal.days_left.utils.genericType
import com.google.gson.Gson
import java.io.IOException
import java.lang.Exception
class FunctionsViewmodel(
val functions: FirebaseFunctionsSource
) : ViewModel(){
fun getAbnList(input: String){
try {
functions.getAbnList(input).continueWith{ task ->
// This continuation runs on either success or failure, but if the task
// has failed then getResult() will throw an Exception which will be
// propagated down.
val result= task.result?.data
result
}.continueWith {
if (!it.isSuccessful){
throw it.exception ?: IOException("Unable to retrieve Abn details")
}
val json = Gson().toJson(it)
val type = genericType<List<AbnObject>>()
Gson().fromJson<List<AbnObject>>(json, type)
}.addOnCompleteListener {
if (!it.isSuccessful){
throw it.exception ?: IOException("Unable to retrieve Abn details")
}
val list = it.result
}
}catch (e: Exception){
e.cause?.printStackTrace()
e.message?.let {
}
}
}
}

View File

@@ -1,12 +1,15 @@
package com.appttude.h_mal.days_left.application
import android.app.Application
import com.appttude.h_mal.days_left.ui.login.AuthViewModelFactory
import com.appttude.h_mal.days_left.data.firebase.FirebaseAuthSource
import com.appttude.h_mal.days_left.data.firebase.FirebaseDataSource
import com.appttude.h_mal.days_left.data.repository.UserRepository
import com.appttude.h_mal.days_left.ui.main.MainViewModelFactory
import com.appttude.h_mal.days_left.data.firebase.FirebaseFunctionsSource
import com.appttude.h_mal.days_left.data.prefs.PreferenceSource
import com.appttude.h_mal.days_left.data.repository.FirebaseRepository
import com.appttude.h_mal.days_left.helper.ShiftHelper
import com.appttude.h_mal.days_left.ui.login.AuthViewModelFactory
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModelFactory
import com.google.gson.Gson
import org.kodein.di.Kodein
import org.kodein.di.KodeinAware
import org.kodein.di.android.x.androidXModule
@@ -15,24 +18,30 @@ import org.kodein.di.generic.instance
import org.kodein.di.generic.provider
import org.kodein.di.generic.singleton
class AppClass : Application(), KodeinAware{
class AppClass : Application(), KodeinAware {
override val kodein = Kodein.lazy {
import(androidXModule(this@AppClass))
bind() from singleton { Gson() }
bind() from singleton { PreferenceSource(instance()) }
bind() from singleton { FirebaseAuthSource() }
bind() from singleton { FirebaseDataSource() }
bind() from singleton { FirebaseFunctionsSource() }
bind() from singleton {
UserRepository(
FirebaseRepository(
instance(),
instance(),
instance()
)
}
bind() from provider { MainViewModelFactory( instance() ) }
bind() from singleton { ShiftHelper() }
// bind() from provider { MainViewModelFactory( instance() ) }
bind() from provider {
ShiftsViewModelFactory( instance() )
ShiftsViewModelFactory(instance(), instance())
}
bind() from provider {
AuthViewModelFactory( instance() )
AuthViewModelFactory(instance())
}
}
}

View File

@@ -1,35 +1,35 @@
package com.appttude.h_mal.days_left.data.firebase
import com.appttude.h_mal.days_left.FirebaseClass
import com.appttude.h_mal.days_left.FirebaseClass.Companion.auth
import com.appttude.h_mal.days_left.FirebaseClass.Companion.mDatabase
import com.google.firebase.auth.FirebaseAuth
import com.appttude.h_mal.days_left.utils.*
import com.google.firebase.database.FirebaseDatabase
const val USER_FIREBASE = "users"
val EMPLOYER_FIREBASE = "employers"
const val SHIFT_FIREBASE = "shifts"
val TASK_FIREBASE = "taskList"
val SHIFT_ID = "shift_id"
val PIECE = "Piece Rate"
val HOURLY = "Hourly"
class FirebaseDataSource{
private val firebaseDatabase: FirebaseDatabase by lazy {
FirebaseDatabase.getInstance()
}
private val mDatabase = firebaseDatabase.reference
val usersRef = mDatabase.child(USER_FIREBASE)
val employersRef = mDatabase.child(EMPLOYER_FIREBASE)
fun allShifts() = mDatabase.child(USER_FIREBASE).child(auth.uid!!).child(
fun allShifts(uid: String) = usersRef.child(uid).child(
SHIFT_FIREBASE
)
fun child(shiftId: String) = mDatabase.child(USER_FIREBASE).child(auth.uid!!).child(
SHIFT_FIREBASE
).child(shiftId)
fun taskObject(abn: String) = mDatabase.child(FirebaseClass.EMPLOYER_FIREBASE).child(abn).child(
FirebaseClass.TASK_FIREBASE
)
fun shiftsRef(uid: String) = usersRef.child(uid).child(SHIFT_FIREBASE)
fun singleShift(uid: String, shiftId: String) = shiftsRef(uid).child(shiftId)
fun deleteItem(uid: String, shiftId: String){
mDatabase.child(USER_FIREBASE).child(uid).child(
SHIFT_FIREBASE
).child(shiftId).removeValue()
}
fun taskObject(abn: String) = mDatabase.child(EMPLOYER_FIREBASE)
.child(abn).child(TASK_LIST)
fun recentEmployers(uid: String) = usersRef.child(uid).child(RECENT_EMPLOYERS)
fun getEmployer(abn: String) = employersRef.child(abn)
}

View File

@@ -1,10 +1,9 @@
package com.appttude.h_mal.days_left.data.firebase
import com.google.android.gms.tasks.Task
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.functions.FirebaseFunctions
import com.google.firebase.functions.HttpsCallableResult
import java.util.HashMap
import java.util.*
class FirebaseFunctionsSource {

View File

@@ -0,0 +1,48 @@
package com.appttude.h_mal.days_left.data.prefs
import android.content.Context
import android.content.SharedPreferences
import androidx.lifecycle.LiveData
import androidx.preference.PreferenceManager
const val SORT_ORDER_CONST = "sort_order"
const val DIR_ORDER_CONST = "direction_order"
class PreferenceSource(
context: Context
) {
val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
fun saveCurrentSortation(sort: String, direction: Int){
preferences.edit()
.putString(SORT_ORDER_CONST, sort)
.putInt(DIR_ORDER_CONST, direction)
.apply()
}
fun loadCurrentSortation(): Pair<String?, Int>{
return Pair(
preferences.getString(SORT_ORDER_CONST, null),
preferences.getInt(DIR_ORDER_CONST, -1)
)
}
fun livePair(): LiveData<Pair<String?, Int>> {
return object: LiveData<Pair<String?, Int>>() {
val listener =
SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
if (key == SORT_ORDER_CONST || key == DIR_ORDER_CONST)
postValue(loadCurrentSortation())
}
override fun onActive() {
super.onActive()
preferences.registerOnSharedPreferenceChangeListener(listener)
}
override fun onInactive() {
preferences.unregisterOnSharedPreferenceChangeListener(listener)
super.onInactive()
}
}
}
}

View File

@@ -17,4 +17,15 @@ abstract class FirebaseExtraction {
}
}
// fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
// this.addTextChangedListener(object : TextWatcher {
// override fun afterTextChanged(editable: Editable?) {
// afterTextChanged.invoke(editable.toString())
// }
//
// override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
//
// override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
// })
// }
}

View File

@@ -6,6 +6,7 @@ import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.Query
import com.google.firebase.database.ValueEventListener
import com.google.gson.reflect.TypeToken
class FirebaseQueryLiveData(
@@ -29,4 +30,113 @@ class FirebaseQueryLiveData(
}
}
@Suppress("UNCHECKED_CAST")
class FirebaseQueryLiveDataTyped<T: Any>(
var query: Query
): LiveData<T>(),ValueEventListener {
override fun onActive() {
query.addValueEventListener(this)
}
override fun onInactive() {
query.removeEventListener(this)
}
override fun onDataChange(p0: DataSnapshot) {
val cls = p0.getValue(object: TypeToken<T>() {}.rawType)
postValue(cls as T)
}
override fun onCancelled(p0: DatabaseError) {
Log.e(this.toString(),p0.message)
}
}
@Suppress("UNCHECKED_CAST")
class FirebaseQueryLiveDataTyped2<T: Any>(
var query: Query,
val clazz: Class<T>
): LiveData<T>(),ValueEventListener {
override fun onActive() {
query.addValueEventListener(this)
}
override fun onInactive() {
query.removeEventListener(this)
}
override fun onDataChange(p0: DataSnapshot) {
val cls = p0.getValue(clazz)
postValue(cls as T)
}
override fun onCancelled(p0: DatabaseError) {
Log.e(this.toString(), p0.message)
}
}
class FirebaseQueryLiveDataList<T: Any>(
var query: Query,
val type: Class<T>
): LiveData<List<T>>(),ValueEventListener {
fun updateQuery(query: Query){
this.query = query
onActive()
}
override fun onActive() {
query.addValueEventListener(this)
}
override fun onInactive() {
query.removeEventListener(this)
}
override fun onDataChange(p0: DataSnapshot) {
val cls = p0.children.map { it.getValue(type)!! }
postValue(cls)
}
override fun onCancelled(p0: DatabaseError) {
Log.e(this.toString(),p0.message)
}
}
@Suppress("UNCHECKED_CAST")
class FirebaseQueryLiveDataMap<T: Any>(
var query: Query,
val type: Class<T>
): LiveData<List<Pair<String, T>>>(),ValueEventListener {
fun updateQuery(query: Query){
this.query = query
onActive()
}
override fun onActive() {
query.addValueEventListener(this)
}
override fun onInactive() {
query.removeEventListener(this)
}
override fun onDataChange(p0: DataSnapshot) {
val cls = p0.children.map { item -> Pair(item.key!!, item.getValue(type)!!) }
postValue(cls)
}
override fun onCancelled(p0: DatabaseError) {
Log.e(this.toString(),p0.message)
}
}

View File

@@ -0,0 +1,77 @@
package com.appttude.h_mal.days_left.helper
import com.appttude.h_mal.days_left.models.TaskObject
import com.appttude.h_mal.days_left.models.TimeObject
import com.appttude.h_mal.days_left.utils.HOURLY_CONST
import com.appttude.h_mal.days_left.utils.PIECE_CONST
import com.appttude.h_mal.days_left.utils.formatToTwoDp
class ShiftHelper {
companion object{
fun String?.ifPieceRate(
piece: (() -> Unit),
hourly: (() -> Unit)
){
if (equals(PIECE_CONST)){
piece.invoke()
}else if (equals(HOURLY_CONST)){
hourly.invoke()
}
}
}
// converts hours float (eg 6.75 hrs into 6 Hours 45 Mins)
fun convertTimeFloat(timeIn: Float?): String? {
if (timeIn == null) return null
if (timeIn < 0) return null
val stringBuilder = StringBuilder()
val hour = timeIn.toInt().takeIf { it > 0 }?.let {
stringBuilder.append(it).append(" hours ")
it
} ?: 0
((timeIn - hour).toInt() * 60).takeIf { it > 0 }?.let{
stringBuilder.append(it).append(" mins")
}
return stringBuilder.toString()
}
fun createTaskSummary(taskObject: TaskObject?): String? {
taskObject ?: return null
val summary = StringBuilder()
summary.append(taskObject.workType)
.append(" - ")
.append(createRateSummary(taskObject))
return summary.toString()
}
// return "$##.## per type"
// type being unit or hour
fun createRateSummary(taskObject: TaskObject?): String {
val summary = StringBuilder()
summary.append("$")
.append(taskObject?.rate?.formatToTwoDp())
.append(" per ")
if (taskObject?.workType.equals(PIECE_CONST)) {
summary.append("unit")
} else {
summary.append("hour")
}
return summary.toString()
}
// returns "HH:mm - HH:mm"
fun getTimeInOutString(timeObject: TimeObject?): String? {
timeObject ?: return null
return timeObject.timeIn + " - " + timeObject.timeOut
}
fun getBreakTimeString(breakMins: Int?): String? {
breakMins ?: return null
val hoursFloat = (breakMins / 60).toFloat()
return convertTimeFloat(hoursFloat)
}
}

View File

@@ -0,0 +1,11 @@
package com.appttude.h_mal.days_left.models
/**
* Data validation state of the login form.
*/
data class UpdateFormState(
var emailError: Int? = null,
var newEmailError: Int? = null,
var passwordError: Int? = null,
var newPasswordError: Int? = null
)

View File

@@ -0,0 +1,52 @@
package com.appttude.h_mal.days_left.ui.addShift
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.navigation.fragment.NavHostFragment
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModel
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModelFactory
import kotlinx.android.synthetic.main.activity_main.*
import org.kodein.di.KodeinAware
import org.kodein.di.android.kodein
import org.kodein.di.generic.instance
class AddShiftActivity : AppCompatActivity(), KodeinAware {
override val kodein by kodein()
private val factory by instance<ShiftsViewModelFactory>()
private val viewModel by viewModels<ShiftsViewModel> { factory }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_shift)
viewModel
//set toolbar
setSupportActionBar(toolbar)
intent.extras?.takeIf { !it.isEmpty }?.let {
}
}
private fun getStackCount(): Int {
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment?
return navHostFragment!!.childFragmentManager.backStackEntryCount
}
override fun onBackPressed() {
if (getStackCount() == 0){
AlertDialog.Builder(this)
.setTitle("Leave?")
.setMessage("Discard current shift? 1122")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes) { _, _ -> finish() }
.create().show()
}else{
super.onBackPressed()
}
}
}

View File

@@ -0,0 +1,234 @@
package com.appttude.h_mal.days_left.ui.addShift
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.cardview.widget.CardView
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.helper.ShiftHelper
import com.appttude.h_mal.days_left.helper.ShiftHelper.Companion.ifPieceRate
import com.appttude.h_mal.days_left.models.AbnObject
import com.appttude.h_mal.days_left.models.ShiftObject
import com.appttude.h_mal.days_left.models.TaskObject
import com.appttude.h_mal.days_left.models.TimeObject
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModel
import com.appttude.h_mal.days_left.ui.main.shiftInfo.DateDialog
import com.appttude.h_mal.days_left.ui.main.shiftInfo.TimeDialog
import com.appttude.h_mal.days_left.utils.*
import kotlinx.android.synthetic.main.fragment_add_shift.*
import org.kodein.di.KodeinAware
import org.kodein.di.android.x.kodein
import org.kodein.di.generic.instance
import java.text.SimpleDateFormat
import java.util.*
class AddShiftFragment : Fragment(), KodeinAware {
var timeObject: TimeObject? = null
var abnObject: AbnObject? = null
var taskObject: TaskObject? = null
override val kodein by kodein()
val helper by instance<ShiftHelper>()
val viewModel by activityViewModels<ShiftsViewModel>()
var id: String? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_add_shift, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
arguments?.takeIf { !it.isEmpty }?.let {
// get shift Id from nav args
id = AddNewShiftActivityArgs.fromBundle(it).shiftId
}
viewModel.currentShift.observe(viewLifecycleOwner, Observer { shift ->
progress_bar.hide()
shift?.abnObject?.let {
abnObject = it
setEmployerCard()
}
shift?.taskObject?.let {
taskObject = it
setTaskCard()
}
shift.timeObject?.let { tO ->
timeObject = tO
setTimeSummary()
}
shift.unitsCount?.formatToTwoDp()?.let { unitsCount ->
units.setText(unitsCount)
}
date.setText(shift.shiftDate)
})
// get single shift and observe
id?.let { id ->
viewModel.retrieveSingleShift(id)
}
// apply on click listeners
select_employer_card.setOnClickListener{
view.navigateTo(R.id.addShift_to_employersFragment_2)
}
select_task_card.setOnClickListener{
view.navigateTo(R.id.addShift_to_tasksFragment)
}
search_button.setOnClickListener(submitListener)
select_times_card.setOnClickListener {
TimeDialog(requireContext(), timeObject) { retrievedTime ->
viewModel.setAddShift(ShiftObject(timeObject = retrievedTime))
setTimeSummary()
}
}
date.apply {
isFocusable = false
setOnClickListener {
val dateDialog =
DateDialog(
this,
requireContext(),
{
viewModel.setAddShift(ShiftObject(shiftDate = it))
}
)
dateDialog.show()
}
}
}
private val submitListener: View.OnClickListener = View.OnClickListener {
if (timeObject == null) {
context?.showToast("Time information missing")
return@OnClickListener
}
if (abnObject == null) {
context?.showToast("Employer information missing")
return@OnClickListener
}
if (taskObject == null) {
context?.showToast("Task information missing")
return@OnClickListener
}
if (date.text.isBlank()) {
context?.showToast("Date missing")
return@OnClickListener
}
if (taskObject?.workType == PIECE_CONST && units.text.isEmpty()) {
context?.showToast("Units information missing")
return@OnClickListener
}
val shiftobj = ShiftObject(
date.text.toString(),
getDateTimeString(),
abnObject,
taskObject,
null,
timeObject
)
units.text?.takeIf { it.isNotBlank() }?.toString()?.trim()?.toFloat()?.let { units ->
shiftobj.unitsCount = units
}
id?.let {
viewModel.updateShift(it, shiftobj)
return@OnClickListener
}
viewModel.postNewShift(shiftobj)
}
private fun setEmployerCard() {
if (lable_1.isVisible) {
toggleViewVisibility(select_employer_card)
}
employer_name.text = abnObject?.companyName
val loc = abnObject?.state + " " + abnObject?.postCode
employer_location.text = loc
}
// Move part to helper method
private fun setTaskCard() {
if (lable_2.isVisible) {
toggleViewVisibility(select_task_card)
}
task.text = taskObject?.task
val summary = helper.createTaskSummary(taskObject)
task_summary.text = summary
taskObject?.workType?.ifPieceRate({
units.visibility = View.VISIBLE
select_times_card.visibility = (View.VISIBLE)
},{
units.visibility = View.GONE
select_times_card.visibility = (View.VISIBLE)
})
}
private fun toggleViewVisibility(cardView: CardView) {
when (cardView.id) {
R.id.select_employer_card -> {
employer_layout.toggleVisibility()
lable_1.toggleVisibility()
return
}
R.id.select_task_card -> {
task_layout.toggleVisibility()
lable_2.toggleVisibility()
return
}
R.id.select_times_card -> {
time_layout.toggleVisibility()
lable_3.toggleVisibility()
return
}
}
}
private fun setTimeSummary() {
if (lable_3.isVisible) {
toggleViewVisibility(select_times_card)
}
time_summary.text = helper.getTimeInOutString(timeObject)
time.text = helper.convertTimeFloat(timeObject?.hours)
timeObject?.breakInt?.takeIf { it > 0 }?.let{
break_holder.show()
break_summary.text = "$it minutes"
return
}
break_holder.hide()
}
private fun getDateTimeString(): String {
val cal = Calendar.getInstance()
val sdf = SimpleDateFormat("dd/MM/yyyy hh:mm:ss", Locale.ENGLISH)
return sdf.format(cal.time)
}
}

View File

@@ -0,0 +1,51 @@
package com.appttude.h_mal.days_left.ui.addShift
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.models.ShiftObject
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModel
import com.appttude.h_mal.days_left.utils.navigateTo
import com.appttude.h_mal.days_left.utils.popBack
import kotlinx.android.synthetic.main.fragment_employers.*
import kotlinx.android.synthetic.main.fragment_list.add_test
class EmployersFragment : Fragment() {
val viewModel: ShiftsViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_employers, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
add_test.setOnClickListener {
view.navigateTo(R.id.employers_to_addEmployerFragment)
}
val employerAdapter = EmployersRecycler {
viewModel.setAddShift(ShiftObject(abnObject = it))
view.popBack()
}
employer_recycler.adapter = employerAdapter
viewModel.getMyEmployers().observeForever {
employerAdapter.apply {
updateList(it)
notifyDataSetChanged()
}
}
}
}

View File

@@ -0,0 +1,142 @@
package com.appttude.h_mal.days_left.ui.addShift
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.models.AbnObject
import com.appttude.h_mal.days_left.utils.inflateLayout
import com.appttude.h_mal.days_left.utils.showToast
import kotlinx.android.synthetic.main.general_list_item.view.*
import kotlinx.android.synthetic.main.icon_text_layout.view.*
class EmployersRecycler(
val selected: ((AbnObject) -> Unit)
): RecyclerView.Adapter<RecyclerView.ViewHolder>(){
var list = mutableListOf<AbnObject>()
fun updateList(abnList: List<AbnObject>){
list.clear()
list.addAll(abnList)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == 0){
val itemOne = parent.context.inflateLayout(R.layout.item_employer_search_empty, parent)
EmptyViewHold(itemOne)
}else{
val itemOne = parent.context.inflateLayout(R.layout.general_list_item, parent)
AbnViewHolder(itemOne)
}
}
override fun getItemCount(): Int {
return if (list.isEmpty()) 1
else list.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is AbnViewHolder){
val item = list?.get(position)
holder.populateView(item)
}
}
override fun getItemViewType(position: Int): Int {
return if (list.size > 0){
1
}else{
0
}
}
internal inner class AbnViewHolder(v: View): RecyclerView.ViewHolder(v){
fun populateView(model: AbnObject?){
itemView.item_title.text = model?.companyName
val locationLayout = itemView.location_layout
val abnLayout = itemView.abn_layout
locationLayout.apply {
val location = "${model?.state} ${model?.postCode}"
icon.setImageResource(R.drawable.marker)
title.text = "Location"
item_text.text = location
}
abnLayout.apply {
icon.setImageResource(R.drawable.ic_baseline_assignment_24)
title.text = "ABN"
item_text.text = model?.abn
}
itemView.setOnClickListener {
model?.let{ selected.invoke(model) }
}
}
}
internal inner class EmptyViewHold(v: View): RecyclerView.ViewHolder(v){
}
// fun filterList(constraint: String?){
// constraint?.let {
// list = list?.filter {
// it.toString().contains(constraint, ignoreCase = true)
// }
// notifyDataSetChanged()
// return
// }
// list = viewModel.shiftData.value
// notifyDataSetChanged()
// }
//
// sealed class Sortation {
// class Name : Sortation()
// class Type : Sortation()
// class DateAdded : Sortation()
// class ShiftDate : Sortation()
// class units: Sortation()
// class default: Sortation()
// }
//
// private fun selectSortation(op: Sortation, reverse: Boolean) {
// list = when (op) {
// is Sortation.Name -> list?.sortedWith(compareBy { it.second.abnObject?.companyName })?.reversed(reverse)
// is Sortation.Type -> list?.sortedWith(compareBy { it.second.taskObject?.task })?.reversed(reverse)
// is Sortation.DateAdded -> list?.sortedWith(compareBy { it.second.dateTimeAdded })?.reversed(reverse)
// is Sortation.ShiftDate -> list?.sortedWith(compareBy { it.second.shiftDate })?.reversed(reverse)
// is Sortation.units -> list?.sortedWith(compareBy { it.second.unitsCount })?.reversed(reverse)
// is Sortation.default -> viewModel.shiftData.value
// }
// }
//
// private fun <T: Any> List<T>.reversed(b: Boolean): List<T>{
// return if (b){
// this.reversed()
// }else {
// this
// }
// }
//
// fun filterShifts(op: Sortation, reverse: Boolean){
// selectSortation(op, reverse)
// notifyDataSetChanged()
// }
// override fun getFilter(): Filter {
// return object : Filter() {
// override fun performFiltering(constraint: CharSequence?): FilterResults {
//
// }
//
// override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
//
// }
// }
// }
}

View File

@@ -0,0 +1,98 @@
package com.appttude.h_mal.days_left.ui.addShift
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.helper.ShiftHelper
import com.appttude.h_mal.days_left.helper.ShiftHelper.Companion.ifPieceRate
import com.appttude.h_mal.days_left.models.ShiftObject
import com.appttude.h_mal.days_left.models.TaskObject
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModel
import com.appttude.h_mal.days_left.utils.HOURLY_CONST
import com.appttude.h_mal.days_left.utils.PIECE_CONST
import com.appttude.h_mal.days_left.utils.inflateLayout
import com.appttude.h_mal.days_left.utils.popBack
import kotlinx.android.synthetic.main.general_list_item.view.*
import kotlinx.android.synthetic.main.icon_text_layout.view.*
import kotlinx.android.synthetic.main.task_list_item.view.*
import org.kodein.di.KodeinAware
import org.kodein.di.android.kodein
import org.kodein.di.generic.instance
class TaskRecycler(
val view: View,
val abn: String?,
val viewModel: ShiftsViewModel
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), KodeinAware {
override val kodein by kodein(view.context)
val helper by instance<ShiftHelper>()
var list: MutableList<TaskObject>? = null
init {
abn?.let {
viewModel.getTasks(abn).observeForever {
list = it as MutableList<TaskObject>?
notifyDataSetChanged()
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val itemOne = view.context.inflateLayout(R.layout.general_list_item, parent)
return TaskViewHolder(itemOne)
//todo: add a empty list view
}
override fun getItemCount(): Int {
return list?.size ?: 1
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val container = holder as TaskViewHolder
val item = list?.get(position)
container.populateView(item)
}
internal inner class TaskViewHolder(v: View): RecyclerView.ViewHolder(v){
fun populateView(model: TaskObject?){
itemView.item_title.text = model?.task
val typeLayout = itemView.location_layout
val rateLayout = itemView.abn_layout
typeLayout.apply {
icon.setImageResource(R.drawable.task)
title.text = "Work type"
model?.workType.ifPieceRate({
item_text.text = PIECE_CONST
},{
item_text.text = HOURLY_CONST
})
}
rateLayout.apply {
icon.setImageResource(R.drawable.ic_baseline_attach_money_24)
title.text = "Pay rate"
item_text.text = helper.createRateSummary(model)
}
itemView.setOnClickListener {
viewModel.setAddShift(ShiftObject(taskObject = model))
view.popBack()
}
}
}
fun addItem(taskObject: TaskObject){
list?.add(taskObject)
notifyDataSetChanged()
}
}

View File

@@ -0,0 +1,46 @@
package com.appttude.h_mal.days_left.ui.addShift
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModel
import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_tasks.*
class TasksFragment : Fragment() {
val viewModel: ShiftsViewModel by activityViewModels()
var abn: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
abn = viewModel.currentShift.value?.abnObject?.abn
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_tasks, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
add_test.setOnClickListener {
view.navigateTo(R.id.action_tasksFragment_to_addTaskFragment)
}
tasks_recycler.adapter =
TaskRecycler(
view,
abn,
viewModel
)
}
}

View File

@@ -2,14 +2,14 @@ package com.appttude.h_mal.days_left.ui.login
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.appttude.h_mal.days_left.data.repository.UserRepository
import com.appttude.h_mal.days_left.data.repository.FirebaseRepository
/**
* ViewModel provider factory to instantiate LoginViewModel.
* Required given LoginViewModel has a non-empty constructor
*/
class AuthViewModelFactory(
private val userRepository: UserRepository
private val firebaseRepository: FirebaseRepository
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
@@ -17,7 +17,7 @@ class AuthViewModelFactory(
if (modelClass.isAssignableFrom(AuthViewModel::class.java)) {
return (
AuthViewModel(
userRepository
firebaseRepository
)
) as T
}

View File

@@ -1,21 +1,18 @@
package com.appttude.h_mal.days_left.ui.login
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.utils.afterTextChanged
import com.appttude.h_mal.days_left.utils.isEmailValid
import com.appttude.h_mal.days_left.utils.navigateTo
import com.appttude.h_mal.days_left.utils.showToast
import kotlinx.android.synthetic.main.fragment_forgot_password.submission_et
import kotlinx.android.synthetic.main.fragment_forgot_password.til_submission
import kotlinx.android.synthetic.main.fragment_forgot_password.*
class ForgotPassword : Fragment() {

View File

@@ -1,13 +1,10 @@
package com.appttude.h_mal.days_left.ui.login
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.splashScreen.SplashFragment
import com.appttude.h_mal.days_left.utils.hide
import com.appttude.h_mal.days_left.utils.show
import com.appttude.h_mal.days_left.utils.showToast
@@ -33,7 +30,7 @@ class FullscreenActivity : AppCompatActivity(), KodeinAware {
}
})
viewModel.operationResult.observe(this, Observer {
viewModel.operationError.observe(this, Observer {
it.getContentIfNotHandled()?.let { message ->
showToast(message)
}

View File

@@ -6,7 +6,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.utils.afterTextChanged
@@ -14,13 +14,12 @@ import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_login.*
import org.kodein.di.KodeinAware
import org.kodein.di.android.x.kodein
import org.kodein.di.generic.instance
class LoginFragment : Fragment(), KodeinAware {
override val kodein by kodein()
private val factory by instance<AuthViewModelFactory>()
private val viewModel: AuthViewModel by viewModels { factory }
private val viewModel: AuthViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
@@ -55,6 +54,13 @@ class LoginFragment : Fragment(), KodeinAware {
}
}
submission_button.setOnClickListener {
viewModel.login(
submission_et.text.toString(),
password.text.toString()
)
}
viewModel.loginFormState.observe(viewLifecycleOwner, Observer {
val loginState = it ?: return@Observer

View File

@@ -1,10 +1,10 @@
package com.appttude.h_mal.days_left.ui.login
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_login_home.*

View File

@@ -1,23 +1,18 @@
package com.appttude.h_mal.days_left.ui.login.registration
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.login.AuthViewModel
import com.appttude.h_mal.days_left.utils.afterTextChanged
import com.appttude.h_mal.days_left.utils.isEmailValid
import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_registration_four.*
import kotlinx.android.synthetic.main.fragment_registration_four.submission_button
import kotlinx.android.synthetic.main.fragment_registration_four.submission_et
import kotlinx.android.synthetic.main.fragment_registration_four.til_submission
import kotlinx.android.synthetic.main.fragment_registration_two.*
/**

View File

@@ -1,16 +1,14 @@
package com.appttude.h_mal.days_left.ui.login.registration
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.Fragment
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.models.registration.RegistrationArgs
import com.appttude.h_mal.days_left.utils.afterTextChanged
import com.appttude.h_mal.days_left.utils.isEmailValid
import com.appttude.h_mal.days_left.utils.isNameValid
import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_registration_two.*

View File

@@ -1,11 +1,11 @@
package com.appttude.h_mal.days_left.ui.login.registration
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.Fragment
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.models.registration.RegistrationArgs
import com.appttude.h_mal.days_left.utils.afterTextChanged
@@ -16,7 +16,7 @@ import kotlinx.android.synthetic.main.fragment_nickname.*
/**
* A simple [Fragment] subclass.
* Use the [RegistrationNicknameFragment.newInstance] factory method to
* Use the [RegistrationNicknameFragment] factory method to
* create an instance of this fragment.
*/
class RegistrationNicknameFragment : Fragment() {
@@ -38,7 +38,7 @@ class RegistrationNicknameFragment : Fragment() {
til_submission.error = null
}
setOnEditorActionListener { textView, id, _ ->
setOnEditorActionListener { _, id, _ ->
if (id == EditorInfo.IME_ACTION_DONE) {
next()
return@setOnEditorActionListener true

View File

@@ -1,21 +1,18 @@
package com.appttude.h_mal.days_left.ui.login.registration
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.Fragment
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.utils.afterTextChanged
import com.appttude.h_mal.days_left.utils.isEmailValid
import com.appttude.h_mal.days_left.utils.isPasswordValid
import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_registration_password.*
/**
* A simple [Fragment] subclass.
* Use the [RegistrationPasswordFragment] factory method to

View File

@@ -1,200 +1,82 @@
package com.appttude.h_mal.days_left.ui.main
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.ActionBarDrawerToggle
import android.view.Menu
import android.view.MenuItem
import androidx.activity.viewModels
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.fragment.app.FragmentManager
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.appttude.h_mal.days_left.*
import com.appttude.h_mal.days_left.ui.login.FullscreenActivity
import com.appttude.h_mal.days_left.FirebaseClass.Companion.SHIFT_FIREBASE
import com.appttude.h_mal.days_left.FirebaseClass.Companion.USER_FIREBASE
import com.appttude.h_mal.days_left.FirebaseClass.Companion.auth
import com.appttude.h_mal.days_left.FirebaseClass.Companion.mDatabase
import com.appttude.h_mal.days_left.models.ShiftObject
import com.appttude.h_mal.days_left.ui.main.home.HomeFragment
import com.appttude.h_mal.days_left.ui.main.list.FragmentList
import com.appttude.h_mal.days_left.ui.main.tools.FragmentTools
import com.google.android.material.navigation.NavigationView
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_drawer_main.*
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.NavigationUI
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.login.AuthViewModel
import com.appttude.h_mal.days_left.ui.login.AuthViewModelFactory
import com.appttude.h_mal.days_left.utils.setVis
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.nav_header_main.view.*
import org.kodein.di.KodeinAware
import org.kodein.di.android.kodein
import org.kodein.di.android.x.kodein
import org.kodein.di.generic.instance
class MainActivity : AppCompatActivity(), KodeinAware {
override val kodein by kodein()
private val factory by instance<MainViewModelFactory>()
private val factory by instance<AuthViewModelFactory>()
private val factory2 by instance<ShiftsViewModelFactory>()
val viewModel: MainViewModel by viewModels{ factory }
val viewModel: AuthViewModel by viewModels{ factory }
companion object{
var shiftList = ArrayList<ShiftObject>()
val ref = mDatabase.child(USER_FIREBASE).child(auth.uid as String).child(SHIFT_FIREBASE)
}
private lateinit var navController : NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_drawer_main)
setContentView(R.layout.activity_main)
ViewModelProvider(this, factory2).get(ShiftsViewModel::class.java)
//setup backstack change listener
supportFragmentManager.addOnBackStackChangedListener(backStackChangedListener)
//set toolbar
setSupportActionBar(toolbar)
//setup fab
fab.setOnClickListener{
val intent = Intent(this, AddShiftActivity::class.java)
startActivity(intent)
}
//setup drawer layout
val toggle = ActionBarDrawerToggle(this,drawer_layout,toolbar,R.string.navigation_drawer_open, R.string.navigation_drawer_close)
drawer_layout.addDrawerListener(toggle)
toggle.syncState()
//apply navigation listener on bottom bar navigation view
navigation.setOnNavigationItemSelectedListener(onNavigationItemSelectedListener)
//setup naviation view
nav_view.setNavigationItemSelectedListener { menuItem ->
menuItem.itemId.let { id ->
if (id == R.id.nav_camera){
val intent = Intent(this, ChangeUserDetailsActivity::class.java)
startActivity(intent)
}
}
drawer_layout.closeDrawer(GravityCompat.START)
true
}
//Setup drawer
setupDrawer(nav_view)
//initialise data for fragments
supportFragmentManager.beginTransaction().replace(R.id.container,
HomeFragment()
).commit()
navigation.id = R.id.navigation_home
// initiate nav host for android navigation
val navHost = supportFragmentManager
.findFragmentById(R.id.container) as NavHostFragment
// instantiate controller for nav host
navController = navHost.navController
// setup bottom bar with tabs
setupBottomBar()
// progress view for async operations
viewModel.operationState.observe(this, Observer {
progressBar2.setVis(it)
})
}
private val onNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_home -> {
supportFragmentManager.beginTransaction().replace(R.id.container,
HomeFragment()
).commit()
return@OnNavigationItemSelectedListener true
}
R.id.navigation_list -> {
supportFragmentManager.beginTransaction().replace(R.id.container,
FragmentList()
).commit()
return@OnNavigationItemSelectedListener true
}
R.id.navigation_tools -> {
supportFragmentManager.beginTransaction().replace(R.id.container,
FragmentTools()
).commit()
return@OnNavigationItemSelectedListener true
}
}
false
private fun setupBottomBar(){
val tabs = setOf(R.id.navigation_home, R.id.navigation_list, R.id.navigation_tools)
val appBarConfiguration = AppBarConfiguration(tabs)
setupActionBarWithNavController(navController, appBarConfiguration)
navigation.setupWithNavController(navController)
}
private val backStackChangedListener = FragmentManager.OnBackStackChangedListener {
supportFragmentManager.fragments[0].javaClass.simpleName.let { fragmentName ->
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu, menu)
return true
}
when (fragmentName){
"HomeFragment" -> {
title = "Home"
}
"ListFragment" -> {
title = "List"
}
"ToolsFragment" -> {
title = "Tools"
}
else -> {
title = getString(R.string.app_name)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
onBackPressed()
true
}
R.id.nav_settings ->{
NavigationUI.onNavDestinationSelected(item, navController)
true
}
else -> {
false
}
}
}
private fun setupDrawer(navigationView: NavigationView){
val header: View = navigationView.getHeaderView(0)
viewModel.getName()?.let {
header.driver_name.text = it
}
viewModel.getEmail()?.let {
header.driver_email.text = it
}
viewModel.getPhotoUrl()?.let {
Picasso.get().load(it).placeholder(R.mipmap.ic_launcher_round)
.into(header.profileImage)
}
logout.setOnClickListener{
viewModel.logout()
val intent = Intent(this, FullscreenActivity::class.java)
startActivity(intent)
finish()
}
}
// fun initiateFragment(){
// progressBar2.visibility = View.VISIBLE
//
// ref.keepSynced(true)
// ref.addValueEventListener(object : ValueEventListener {
// override fun onCancelled(p0: DatabaseError) {
// progressBar2.visibility = View.GONE
// }
//
// override fun onDataChange(p0: DataSnapshot) {
// progressBar2.visibility = View.GONE
//
// if(shiftList.isNotEmpty()){
// shiftList.clear()
// }
//
// for(postSnapshot in p0.children){
// shiftList.add(postSnapshot.getValue(ShiftObject::class.java)!!)
// }
//
// Log.i("firebase", "shiftlist count = " + shiftList.size)
//
// if (shiftList.size > 0){
// if(fragmentManager.fragments.size == 0){
// //apply navigation listener on bottom bar navigation view
// navigation.setOnNavigationItemSelectedListener(onNavigationItemSelectedListener)
// //add first fragment
// fragmentManager.beginTransaction().replace(R.id.container,HomeFragment()).commit()
// navigation.setSelectedItemId(R.id.navigation_home)
// }
// }else{
// Toast.makeText(getBaseContext() , "Cannot load data", Toast.LENGTH_SHORT).show()
// }
//
// }
// })
// }
}

View File

@@ -2,14 +2,14 @@ package com.appttude.h_mal.days_left.ui.main
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.appttude.h_mal.days_left.data.repository.UserRepository
import com.appttude.h_mal.days_left.data.repository.FirebaseRepository
/**
* ViewModel provider factory to instantiate LoginViewModel.
* Required given LoginViewModel has a non-empty constructor
*/
class MainViewModelFactory(
private val userRepository: UserRepository
private val firebaseRepository: FirebaseRepository
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
@@ -17,7 +17,7 @@ class MainViewModelFactory(
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return (
MainViewModel(
userRepository
firebaseRepository
)
) as T
}

View File

@@ -1,88 +1,204 @@
package com.appttude.h_mal.days_left.ui.main
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import com.appttude.h_mal.days_left.data.firebase.FirebaseDataSource
import com.appttude.h_mal.days_left.firebaseUtils.FirebaseQueryLiveData
import com.appttude.h_mal.days_left.data.repository.FirebaseRepository
import com.appttude.h_mal.days_left.firebaseUtils.FirebaseQueryLiveDataList
import com.appttude.h_mal.days_left.firebaseUtils.FirebaseQueryLiveDataMap
import com.appttude.h_mal.days_left.firebaseUtils.FirebaseQueryLiveDataTyped2
import com.appttude.h_mal.days_left.models.AbnObject
import com.appttude.h_mal.days_left.models.ShiftObject
import com.appttude.h_mal.days_left.models.TaskObject
import com.appttude.h_mal.days_left.utils.Event
import com.appttude.h_mal.days_left.utils.getResults
import com.appttude.h_mal.days_left.utils.safeFirebaseResult
import com.google.firebase.database.DataSnapshot
import java.util.HashSet
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.ValueEventListener
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
class ShiftsViewModel(
val database: FirebaseDataSource
): ViewModel() {
val repository: FirebaseRepository,
val gson: Gson
) : ViewModel() {
val shifts = database.allShifts()
val shiftData = FirebaseQueryLiveData(shifts)
// Live date of operation success
val operationState = MutableLiveData<Boolean>()
val operationResult = MutableLiveData<Event<Pair<Boolean, String?>>>()
val shifts = repository.getShiftList()
val shiftData = FirebaseQueryLiveDataMap(shifts, ShiftObject::class.java)
val liveData = MutableLiveData<Triple<List<ShiftObject?>, Int, IntArray>>()
val currentShift = MutableLiveData<ShiftObject>()
init {
shiftData.observeForever {
val list = it.mapSnapToShiftList()
val uniqueEntries = countDistinct(list)
val shiftTypeCount = countShiftType(list)
val shifts = it.map { item -> item.second }
val uniqueEntries = countDistinct(shifts)
val shiftTypeCount = countShiftType(shifts)
liveData.value = Triple(
list,
shifts,
uniqueEntries,
shiftTypeCount
)
}
}
fun retrieveSingleShift(id: String){
repository.getSingleShift(id).getResults { dataSnapshot ->
dataSnapshot?.getValue(ShiftObject::class.java)?.let {
currentShift.postValue(it)
}
}
}
fun getSingleShift(id: String): FirebaseQueryLiveDataTyped2<ShiftObject> {
return FirebaseQueryLiveDataTyped2<ShiftObject>(
repository.getSingleShift(id),
ShiftObject::class.java
)
}
fun getTasks(abn: String): FirebaseQueryLiveDataList<TaskObject> {
return FirebaseQueryLiveDataList(repository.tasks(abn), TaskObject::class.java)
}
fun deleteShift(id: String) {
repository.deleteSingleShift(id)
}
fun updateShift(id: String, shiftObject: ShiftObject) {
operationState.postValue(true)
repository.updateShift(id, shiftObject).safeFirebaseResult({
operationResult.postValue(Event(Pair(true, "Update Successful")))
}, {
operationResult.postValue(Event(Pair(false, it)))
}, {
operationState.postValue(false)
})
}
fun postNewShift(shiftObject: ShiftObject) {
operationState.postValue(true)
repository.postShift(shiftObject).safeFirebaseResult({
operationResult.postValue(Event(Pair(true, "Post Successful")))
}, {
operationResult.postValue(Event(Pair(false, it)))
}, {
operationState.postValue(false)
})
}
fun getMyEmployers(): LiveData<MutableList<AbnObject>> {
val query = repository.getRecentEmployers()
return object : LiveData<MutableList<AbnObject>>(), ValueEventListener {
override fun onActive() {
query.addValueEventListener(this)
}
override fun onInactive() {
query.removeEventListener(this)
}
override fun onDataChange(snapshot: DataSnapshot) {
val data = snapshot.children.mapNotNull { it.key }
Log.i("GetEmployers", "size = ${data.size}")
clearData()
if (data.isEmpty()) return
data.forEach { item ->
repository.getEmployer(item).getResults { ds ->
ds?.getValue(AbnObject::class.java)?.let { abn ->
Log.i("GetEmployers", "abn = ${abn.abn}")
addItems(abn)
}
}
}
}
fun <T> LiveData<MutableList<T>>.addItems(item: T) {
val updatedItems = this.value ?: mutableListOf()
updatedItems.add(item)
this.value = updatedItems
}
fun <T> LiveData<MutableList<T>>.clearData() {
this.value = mutableListOf()
}
override fun postValue(value: MutableList<AbnObject>?) {
Log.i("GetEmployers", "posted size = ${value?.size}")
super.postValue(value)
}
override fun onCancelled(error: DatabaseError) {}
}
}
fun searchForAbn(
input: String,
output: ((List<AbnObject>) -> Unit)
){
operationState.postValue(true)
repository.getAbnList(input).safeFirebaseResult({
val list = it?.data as ArrayList<*>
val abnList = list.map { item ->
convertAny<AbnObject>(item)
}
output.invoke(abnList)
},{
operationResult.postValue(Event(Pair(false, it)))
},{
operationState.postValue(false)
})
}
private inline fun <reified T> convertAny(item: Any): T {
val type = object: TypeToken<T>() {}.type
val itemAsString = gson.toJson(item)
return gson.fromJson<T>(itemAsString, type)
}
fun setAddShift(shiftObject: ShiftObject){
val updatedItems = currentShift.value ?: ShiftObject()
shiftObject.apply {
abnObject?.let {
updatedItems.abnObject = it
}
taskObject?.let {
updatedItems.taskObject = it
}
timeObject?.let {
updatedItems.timeObject = it
}
unitsCount?.let {
updatedItems.unitsCount = it
}
shiftDate?.let {
updatedItems.shiftDate = it
}
}
currentShift.postValue(updatedItems)
}
private fun countDistinct(list: List<ShiftObject?>): Int {
return list.distinctBy { it?.shiftDate }.size
return list.distinctBy { it?.shiftDate }.size
}
private fun countShiftType(list: List<ShiftObject?>): IntArray {
val i = list.filter { it?.taskObject?.workType.equals("Hourly") }.size
val i = list.filter { it?.taskObject?.workType.equals("Hourly") }.size
val j = list.size - i
return intArrayOf(i, j)
}
private fun DataSnapshot.mapSnapToShiftList(): List<ShiftObject?> = this.children.map {
it.getValue(ShiftObject::class.java)
}
// private fun calculateAccumulatedPay(type: Int): Float {
// var pay = 0f
//
// for (shiftObject in shiftList) {
// shiftObject?.let {
// when (type){
// 0 -> {
// if (it.taskObject?.workType == "Hourly") {
// pay += it.taskObject?.rate?.times((it.timeObject!!.hours - it.timeObject!!.breakEpoch))
// ?: pay
// }
// }
// 1 -> {
// if (it.taskObject?.workType == "Piece Rate") {
// pay += it.taskObject?.rate?.times(it.unitsCount!!) ?: pay
// }
// }
// else -> {
// if (it.taskObject?.workType == "Hourly") {
// pay += it.taskObject?.rate?.times((it.timeObject!!.hours - it.timeObject!!.breakEpoch))
// ?: pay
// } else {
// pay += it.taskObject?.rate?.times(it.unitsCount!!) ?: pay
// }
// }
// }
// }
// }
//
// return pay
// }
private fun totalPay(): Float{
return 0.0f
}
}

View File

@@ -2,14 +2,16 @@ package com.appttude.h_mal.days_left.ui.main
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.appttude.h_mal.days_left.data.firebase.FirebaseDataSource
import com.appttude.h_mal.days_left.data.repository.FirebaseRepository
import com.google.gson.Gson
/**
* ViewModel provider factory to instantiate LoginViewModel.
* Required given LoginViewModel has a non-empty constructor
*/
class ShiftsViewModelFactory(
private val firebaseDatabase: FirebaseDataSource
private val firebaseDatabase: FirebaseRepository,
private val gson: Gson
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
@@ -17,7 +19,8 @@ class ShiftsViewModelFactory(
if (modelClass.isAssignableFrom(ShiftsViewModel::class.java)) {
return (
ShiftsViewModel(
firebaseDatabase
firebaseDatabase,
gson
)
) as T
}

View File

@@ -0,0 +1,152 @@
package com.appttude.h_mal.days_left.ui.main.home
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.models.ShiftObject
import com.appttude.h_mal.days_left.models.TimeObject
import com.appttude.h_mal.days_left.utils.*
class RecyclerGridAdapter(
val context: Context,
private val shiftList: List<ShiftObject?>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var uniqueEntries: Int = 0
var typeCount: IntArray
init {
uniqueEntries = countDistinct()
typeCount = countShiftType()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val itemThree = context.inflateLayout(R.layout.item_three, parent)
return ItemThree(itemThree)
}
override fun getItemCount(): Int {
return 2
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val viewCounting = holder as ItemThree
val cardTitle = viewCounting.cardTitle
val cardIcon = viewCounting.cardIcon
val units = viewCounting.units
val totalEarned = viewCounting.totalEarned
val total: String
when (position){
0 ->{
cardTitle.text = HOURLY_CONST
cardIcon.setImageResource(R.drawable.clock_icon)
val hours = calculateHours().formatToTwoDp() + " hours"
units.text = hours
total = calculateAccumulatedPay(Counting.hourly()).formatToTwoDp() + " hours"
}
1 ->{
cardTitle.text = PIECE_CONST
cardTitle.setTextColor(context.loadColour(R.color.three))
cardIcon.setImageResource(R.drawable.piece)
cardIcon.rotation = 270f
val pieces = calculateUnits()?.formatToTwoDp()
units.text = pieces
total = String.format("%.2f", calculateAccumulatedPay(Counting.piece()))
}
else -> return
}
totalEarned.text = total
}
internal inner class ItemThree(itemView: View) : RecyclerView.ViewHolder(itemView) {
val cardTitle: TextView = itemView.findViewById(R.id.card_title)
val cardIcon: ImageView = itemView.findViewById(R.id.card_icon)
val units: TextView = itemView.findViewById(R.id.units)
val totalEarned: TextView = itemView.findViewById(R.id.total_earned)
}
private fun calculateHours(): Double {
return filterShifts(Counting.hourly()).sumByDouble {
getTotalHours(it?.timeObject)
}
}
private fun getTotalHours(time: TimeObject?): Double {
val breakTime = time?.breakInt?.toDouble() ?: return 0.00
val hours = time.hours?.toDouble() ?: return 0.00
return (hours.minus(breakTime))
}
private fun calculateUnits(): Double? {
return filterShifts(Counting.piece()).sumByDouble {
it?.unitsCount?.toDouble() ?: 0.00
}
}
private fun calculateAccumulatedPay(op: Counting): Double {
val shifts = filterShifts(op)
return when (op) {
is Counting.hourly -> {
shifts.sumByDouble {
getTotalForHourly(it)
}
}
is Counting.piece -> {
shifts.sumByDouble {
getTotalForPiece(it)
}
}
is Counting.both -> {
shifts.sumByDouble {
getTotalForHourly(it) + getTotalForPiece(it)
}
}
}
}
private fun getTotalForHourly(shift: ShiftObject?): Double {
val rate = shift?.taskObject?.rate ?: return 0.00
val hours = getTotalHours(shift.timeObject)
return rate * hours
}
private fun getTotalForPiece(shift: ShiftObject?): Double {
val rate = shift?.taskObject?.rate ?: return 0.00
val units = shift.unitsCount ?: return 0.00
return (rate * units).toDouble()
}
sealed class Counting {
class hourly : Counting()
class piece : Counting()
class both : Counting()
}
private fun filterShifts(op: Counting) = when (op) {
is Counting.hourly -> shiftList.filter { it?.taskObject?.workType == HOURLY_CONST }
is Counting.piece -> shiftList.filter { it?.taskObject?.workType == PIECE_CONST }
is Counting.both -> shiftList
}
private fun countDistinct(): Int = shiftList.distinctBy {
it?.shiftDate
}.count()
private fun countShiftType(): IntArray {
filterShifts(Counting.hourly())
val i = filterShifts(Counting.hourly()).count()
val j = filterShifts(Counting.piece()).count()
return intArrayOf(i, j)
}
}

View File

@@ -1,36 +1,29 @@
package com.appttude.h_mal.days_left.ui.main.list
import android.app.AlertDialog
import android.content.DialogInterface
import android.content.DialogInterface.BUTTON_POSITIVE
import android.content.Intent
import android.database.DataSetObserver
import android.os.Bundle
import android.view.*
import android.widget.AdapterView
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.activityViewModels
import com.appttude.h_mal.days_left.*
import com.appttude.h_mal.days_left.CustomDialog.Companion.dateSelectionFrom
import com.appttude.h_mal.days_left.CustomDialog.Companion.dateSelectionTo
import com.appttude.h_mal.days_left.FirebaseClass.Companion.SHIFT_ID
import com.appttude.h_mal.days_left.models.AbnObject
import com.appttude.h_mal.days_left.models.ShiftObject
import com.appttude.h_mal.days_left.ui.main.MainActivity
import com.appttude.h_mal.days_left.ui.main.MainActivity.Companion.ref
import androidx.navigation.fragment.findNavController
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.addShift.AddNewShiftActivity
import com.appttude.h_mal.days_left.ui.addShift.AddShiftActivity
import com.appttude.h_mal.days_left.ui.addShift.AddShiftFragment
import com.appttude.h_mal.days_left.ui.login.FullscreenActivity
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModel
import com.firebase.ui.database.FirebaseRecyclerAdapter
import com.google.firebase.FirebaseOptions
import com.google.firebase.database.Query
import kotlinx.android.synthetic.main.dialog_previous_abns_used.view.*
import com.appttude.h_mal.days_left.ui.main.list.ShiftListRecyclerAdapter.Sortation
import com.appttude.h_mal.days_left.ui.splashScreen.SplashFragment
import com.appttude.h_mal.days_left.utils.navigateTo
import com.appttude.h_mal.days_left.utils.showToast
import kotlinx.android.synthetic.main.fragment_list.*
import java.util.*
import kotlin.collections.ArrayList
class FragmentList : androidx.fragment.app.Fragment() {
class FragmentList : androidx.fragment.app.Fragment(), SearchView.OnQueryTextListener {
val viewModel: ShiftsViewModel by activityViewModels()
lateinit var fireAdapter: FireAdapter
lateinit var fireAdapter: ShiftListRecyclerAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
@@ -43,37 +36,30 @@ class FragmentList : androidx.fragment.app.Fragment() {
super.onViewCreated(view, savedInstanceState)
//set custom firebase adapter on listview
add_test.setOnClickListener {
view.navigateTo(R.id.list_to_addShiftActivity)
}
fireAdapter = FireAdapter(
activity,
ShiftObject::class.java,
R.layout.list_item,
viewModel.shifts
)
fireAdapter =
ShiftListRecyclerAdapter(
view,
viewModel
)
page_two_list.apply {
recycler_view.apply {
adapter = fireAdapter
onItemClickListener =
AdapterView.OnItemClickListener { _, _, position, _ ->
val refId = fireAdapter.getId(position)
val intent = Intent(activity, AddShiftActivity::class.java)
intent.putExtra(SHIFT_ID, refId)
startActivity(intent)
}
onItemLongClickListener =
AdapterView.OnItemLongClickListener { _, _, position, _ ->
AlertDialog.Builder(context).apply {
setTitle("Are you sure you want to delete?")
setNegativeButton(android.R.string.no, null)
setPositiveButton(android.R.string.yes) { _, _ ->
fireAdapter.getRef(position).removeValue()
}
create().show()
}
true
}
// onItemLongClickListener =
// AdapterView.OnItemLongClickListener { _, _, position, _ ->
// AlertDialog.Builder(context).apply {
// setTitle("Are you sure you want to delete?")
// setNegativeButton(android.R.string.no, null)
// setPositiveButton(android.R.string.yes) { _, _ ->
// fireAdapter.getRef(position).removeValue()
// }
// create().show()
// }
// true
// }
}
setHasOptionsMenu(true)
}
@@ -81,14 +67,14 @@ class FragmentList : androidx.fragment.app.Fragment() {
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.menu_list_fragment, menu)
val menuItem = menu.findItem(R.id.app_bar_filter)
val searchView = menuItem.actionView as SearchView
searchView.setOnQueryTextListener(this)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.app_bar_filter -> {
filterData()
return false
}
R.id.app_bar_soft -> {
sortData()
return false
@@ -106,31 +92,15 @@ class FragmentList : androidx.fragment.app.Fragment() {
setSingleChoiceItems(groupName, checkedItem) { dialog, item ->
when (item) {
0 -> {
val q1 =
viewModel.shifts.orderByChild("abnObject/companyName").equalTo("GREEN CLOUD NURSERY")
fireAdapter.notifyDataSetChanged()
// fireAdapter = FireAdapter(
// activity,
// ShiftObject::class.java,
// R.layout.list_item,
// q1
// )
fireAdapter.filterShifts(Sortation.Name())
}
1 -> {
fireAdapter.filterShifts(Sortation.DateAdded())
}
2 ->{
fireAdapter.filterShifts(Sortation.ShiftDate())
}
1 -> fireAdapter = FireAdapter(
activity,
ShiftObject::class.java,
R.layout.list_item,
ref.orderByChild("dateTimeAdded")
)
2 -> fireAdapter = FireAdapter(
activity,
ShiftObject::class.java,
R.layout.list_item,
ref.orderByChild("shiftDate")
)
}
page_two_list.adapter = fireAdapter
dialog.dismiss()
}
create().show()
@@ -138,116 +108,130 @@ class FragmentList : androidx.fragment.app.Fragment() {
}
private fun filterData() {
val groupName = arrayOf("Name", "Date Added", "Shift Type")
val checkedItem = -1
override fun onQueryTextSubmit(query: String?): Boolean {
val builder = AlertDialog.Builder(context)
builder.setTitle("Filter by:")
builder.setSingleChoiceItems(
groupName,
checkedItem,
DialogInterface.OnClickListener { dialog, item ->
dialog.dismiss()
when (item) {
0 -> {
val dialogBuilder = AlertDialog.Builder(context)
dialogBuilder.setTitle("Select Employer:")
//get layout
val dialogView = View.inflate(
context,
R.layout.dialog_previous_abns_used, null
)
//hide button
dialogView.button_list_dialog.visibility = View.GONE
//get listview
val listView = dialogView.list_item_list_dialog
//get unique abn objects
val uniqueAbnObjects = turnToUniqueAbnObject(MainActivity.shiftList)
//populate list in view
listView.adapter =
AbnListAdapter(
requireContext(),
uniqueAbnObjects as MutableList<AbnObject>
)
//on item click listener
listView.setOnItemClickListener(AdapterView.OnItemClickListener { parent, view, position, id ->
applyFilter(uniqueAbnObjects[position].abn!!, null)
})
//set view on dialog
dialogBuilder.setView(dialogView)
dialogBuilder.create().show()
}
1 -> {
val customDialog =
CustomDialog(requireContext())
customDialog.setButton(BUTTON_POSITIVE,
getContext()?.getString(android.R.string.yes),
DialogInterface.OnClickListener { dialogNew, which ->
//interface results back
if (dateSelectionFrom != dateSelectionTo) {
applyFilter(dateSelectionFrom, dateSelectionTo)
}
customDialog.dismiss()
})
customDialog.create()
}
2 -> {
val typeDialog = AlertDialog.Builder(context)
val typeString = arrayOf("Hourly", "Piece Rate")
typeDialog.setSingleChoiceItems(
arrayOf("Hourly", "Piece Rate"), -1
) { dialog, which ->
val q1 =
ref.orderByChild("taskObject/workType").equalTo(typeString[which])
fireAdapter = FireAdapter(
activity,
ShiftObject::class.java,
R.layout.list_item,
q1
)
page_two_list.adapter = fireAdapter
}
typeDialog.create().show()
}
}
})
return true
}
fun turnToUniqueAbnObject(shifts: ArrayList<ShiftObject>): List<AbnObject> {
val abnList = mutableListOf<AbnObject>()
shifts.forEach { shiftObject ->
shiftObject.abnObject?.let { abnList.add(it) }
override fun onQueryTextChange(newText: String?): Boolean {
if (newText.isNullOrBlank()){
fireAdapter.filterList(null)
}else{
fireAdapter.filterList(newText)
}
return abnList.distinct()
return false
}
fun applyFilter(arg1: String, arg2: String?) {
val q1: Query
if (arg2 == null) {
q1 = ref.orderByChild("abnObject/abn").equalTo(arg1)
} else {
q1 = ref.orderByChild("shiftDate").startAt(arg1).endAt(arg2)
}
fireAdapter = FireAdapter(
activity,
ShiftObject::class.java,
R.layout.list_item,
q1
)
page_two_list.adapter = fireAdapter
}
// private fun filterData() {
// val groupName = arrayOf("Name", "Date Added", "Shift Type")
// val checkedItem = -1
//
// val builder = AlertDialog.Builder(context)
// builder.setTitle("Filter by:")
// builder.setSingleChoiceItems(
// groupName,
// checkedItem,
// DialogInterface.OnClickListener { dialog, item ->
// dialog.dismiss()
//
// when (item) {
// 0 -> {
// val dialogBuilder = AlertDialog.Builder(context)
// dialogBuilder.setTitle("Select Employer:")
// //get layout
// val dialogView = View.inflate(
// context,
// R.layout.dialog_previous_abns_used, null
// )
// //hide button
// dialogView.button_list_dialog.visibility = View.GONE
// //get listview
// val listView = dialogView.list_item_list_dialog
// //get unique abn objects
// val uniqueAbnObjects = viewModel.shifts
// //populate list in view
// listView.adapter =
// AbnListAdapter(
// requireContext(),
// uniqueAbnObjects
// )
// //on item click listener
// listView.setOnItemClickListener(AdapterView.OnItemClickListener { parent, view, position, id ->
// applyFilter(uniqueAbnObjects[position].abn!!, null)
// })
// //set view on dialog
// dialogBuilder.setView(dialogView)
//
// dialogBuilder.create().show()
//
// }
// 1 -> {
// val customDialog =
// CustomDialog(requireContext())
//
// customDialog.setButton(BUTTON_POSITIVE,
// getContext()?.getString(android.R.string.yes),
// DialogInterface.OnClickListener { dialogNew, which ->
// //interface results back
// if (dateSelectionFrom != dateSelectionTo) {
// applyFilter(dateSelectionFrom, dateSelectionTo)
// }
//
// customDialog.dismiss()
// })
//
// customDialog.create()
// }
// 2 -> {
// val typeDialog = AlertDialog.Builder(context)
// val typeString = arrayOf("Hourly", "Piece Rate")
//
// typeDialog.setSingleChoiceItems(
// arrayOf("Hourly", "Piece Rate"), -1
// ) { dialog, which ->
// val q1 =
// ref.orderByChild("taskObject/workType").equalTo(typeString[which])
//
// fireAdapter = FireAdapter(
// activity,
// ShiftObject::class.java,
// R.layout.list_item,
// q1
// )
// page_two_list.adapter = fireAdapter
// }
// typeDialog.create().show()
// }
// }
// })
// }
//
// fun turnToUniqueAbnObject(shifts: ArrayList<ShiftObject>): List<AbnObject> {
// val abnList = mutableListOf<AbnObject>()
//
// shifts.forEach { shiftObject ->
// shiftObject.abnObject?.let { abnList.add(it) }
// }
//
// return abnList.distinct()
// }
//
// fun applyFilter(arg1: String, arg2: String?) {
// val q1: Query
// if (arg2 == null) {
// q1 = ref.orderByChild("abnObject/abn").equalTo(arg1)
// } else {
// q1 = ref.orderByChild("shiftDate").startAt(arg1).endAt(arg2)
// }
//
// fireAdapter = FireAdapter(
// activity,
// ShiftObject::class.java,
// R.layout.list_item,
// q1
// )
// page_two_list.adapter = fireAdapter
// }
}

View File

@@ -0,0 +1,156 @@
package com.appttude.h_mal.days_left.ui.main.list
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.RecyclerView
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.models.AbnObject
import com.appttude.h_mal.days_left.models.ShiftObject
import com.appttude.h_mal.days_left.models.TaskObject
import com.appttude.h_mal.days_left.utils.HOURLY_CONST
import com.appttude.h_mal.days_left.utils.formatToTwoDp
import kotlinx.android.synthetic.main.list_item_title.view.*
class ShiftDetailsRecycler(
val context: Context,
liveShift: LiveData<ShiftObject>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(){
var shift: ShiftObject? = null
init {
liveShift.observeForever{
shift = it
notifyDataSetChanged()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
1 -> {
val item = LayoutInflater.from(context)
.inflate(R.layout.list_item_title, parent, false)
ItemHeader(item)
}
else ->{
val item = LayoutInflater.from(context)
.inflate(R.layout.item_two_layout, parent, false)
ItemOne(item)
}
}
}
override fun getItemCount(): Int{
return if (shift == null){
1
}else{
15
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder.itemViewType) {
// header
1 -> {
val viewHolderCurrent = holder as ItemHeader
viewHolderCurrent.title.text = when(position){
0 -> context.getString(R.string.employer_details)
4 -> context.getString(R.string.shift_details)
10 -> context.getString(R.string.date_details)
else -> ""
}
}
2 -> {
val viewHolderCurrent = holder as ItemOne
val pair = getItemDetails(position)
viewHolderCurrent.top.text = pair.first
viewHolderCurrent.bottom.text = pair.second
}
}
}
override fun getItemViewType(position: Int): Int {
return when (position) {
0,4,10 -> 1
else -> 2
}
}
private fun getItemDetails(position: Int): Pair<String, String?> {
return when(position){
1 -> Pair(context.getString(R.string.employer_name_title), shift?.abnObject?.companyName)
2 -> Pair(context.getString(R.string.employer_abn_title), shift?.abnObject?.abn)
3 -> Pair(context.getString(R.string.employer_location_title), getLocation(shift?.abnObject) )
5 -> Pair(context.getString(R.string.shift_date_details), shift?.shiftDate)
6 -> Pair(context.getString(R.string.shift_task_details), shift?.taskObject?.task)
7 -> Pair(context.getString(R.string.shift_rate_details), getRateOfPay(shift?.taskObject))
8 -> Pair(context.getString(R.string.shift_units_details), calculateUnitString())
9 -> Pair(context.getString(R.string.shift_total_pay_details), calculateTotalPay().toString())
11 -> Pair(context.getString(R.string.shift_time_in_details), shift?.timeObject?.timeIn)
12 -> Pair(context.getString(R.string.shift_time_out_details), shift?.timeObject?.timeOut)
13 -> Pair(context.getString(R.string.shift_break_details), getBreak())
14 -> Pair(context.getString(R.string.shift_hours_details), getHours().toString())
else -> Pair("","")
}
}
private fun getLocation(abnObject: AbnObject?): String? {
return abnObject?.let {
"${it.postCode} ${it.state}"
}
}
private fun getRateOfPay(task: TaskObject?): String? {
return task?.let {
val rate = "$${task.rate?.formatToTwoDp()}"
val type = if (task.workType == HOURLY_CONST){
"hour"
}else{
"unit"
}
"$rate per $type"
}
}
fun calculateUnitString(): String? {
return getUnits()?.formatToTwoDp()
}
private fun getUnits(): Float? {
return if (shift?.taskObject?.workType == HOURLY_CONST){
getHours()
}else{
shift?.unitsCount
}
}
fun getHours() = shift?.timeObject?.hours ?: 0.00f
fun calculateTotalPay(): Float {
val units: Float = getUnits() ?: return 0.00f
val rate: Float = shift?.taskObject?.rate ?: return 0.00f
return units * rate
}
fun getBreak(): String {
val breakMins = shift?.timeObject?.breakInt ?: 0
return breakMins.toString()
}
internal inner class ItemOne(itemView: View) : RecyclerView.ViewHolder(itemView) {
val top = itemView.findViewById<TextView>(android.R.id.text1)
val bottom = itemView.findViewById<TextView>(android.R.id.text2)
}
internal inner class ItemHeader(itemView: View) : RecyclerView.ViewHolder(itemView) {
val title: TextView = itemView.title
}
}

View File

@@ -0,0 +1,170 @@
package com.appttude.h_mal.days_left.ui.main.list
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.helper.ShiftHelper
import com.appttude.h_mal.days_left.helper.ShiftHelper.Companion.ifPieceRate
import com.appttude.h_mal.days_left.models.ShiftObject
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModel
import com.appttude.h_mal.days_left.utils.hide
import com.appttude.h_mal.days_left.utils.inflateLayout
import com.appttude.h_mal.days_left.utils.navigateTo
import com.appttude.h_mal.days_left.utils.show
import kotlinx.android.synthetic.main.list_item.view.*
import org.kodein.di.KodeinAware
import org.kodein.di.android.kodein
import org.kodein.di.generic.instance
class ShiftListRecyclerAdapter(
val view: View,
val viewModel: ShiftsViewModel
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), KodeinAware {
override val kodein by kodein(view.context)
val helper by instance<ShiftHelper>()
var list: List<Pair<String, ShiftObject>>? = null
init {
viewModel.shiftData.observeForever {
list = it
notifyDataSetChanged()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val itemOne = view.context.inflateLayout(R.layout.list_item, parent)
return ShiftViewHolder(itemOne)
}
override fun getItemCount(): Int {
return list?.size ?: 1
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val container = holder as ShiftViewHolder
val item = list?.get(position)?.second
container.populateView(item)
container.itemView.setOnClickListener {
val id = list?.get(position)?.first
id?.let {
val actions = FragmentListDirections.listToShiftOverviewFragment(id)
view.navigateTo(actions)
}
}
}
internal inner class ShiftViewHolder(v: View) : RecyclerView.ViewHolder(v) {
fun populateView(model: ShiftObject?) {
itemView.item_title.text = model?.abnObject?.abn
itemView.date?.text = model?.shiftDate
itemView.task_name?.text = model?.taskObject?.task
itemView.type?.text = model?.taskObject?.workType
val locationString: String =
model?.abnObject?.state + " - " + model?.abnObject?.postCode
itemView.location?.text = locationString
val breakHolder = itemView.container_four
itemView.item_title?.text = model?.abnObject?.companyName
val s = helper.createTaskSummary(model?.taskObject)
itemView.type?.text = s
model?.taskObject?.workType?.ifPieceRate({
itemView.container_three?.hide()
itemView.container_five?.show()
itemView.units?.text = model.unitsCount.toString()
}, {
itemView.container_three?.hide()
itemView.container_five?.show()
itemView.time?.text = helper.getTimeInOutString(model.timeObject)
itemView.units?.text = helper.convertTimeFloat(model.timeObject?.hours)
model.timeObject!!.breakInt?.takeIf { it > 0 }?.let { mins ->
breakHolder?.show()
itemView.break_time?.text =
helper.getBreakTimeString(model.timeObject?.breakInt)
return@ifPieceRate
}
breakHolder?.hide()
})
}
}
fun filterList(constraint: String?) {
constraint?.let {
list = list?.filter {
it.toString().contains(constraint, ignoreCase = true)
}
notifyDataSetChanged()
return
}
list = viewModel.shiftData.value
notifyDataSetChanged()
}
sealed class Sortation {
class Name : Sortation()
class Type : Sortation()
class DateAdded : Sortation()
class ShiftDate : Sortation()
class units : Sortation()
class default : Sortation()
}
private fun selectSortation(op: Sortation, reverse: Boolean) {
list = when (op) {
is Sortation.Name -> list?.sortedWith(compareBy { it.second.abnObject?.companyName })
?.reversed(reverse)
is Sortation.Type -> list?.sortedWith(compareBy { it.second.taskObject?.task })
?.reversed(reverse)
is Sortation.DateAdded -> list?.sortedWith(compareBy { it.second.dateTimeAdded })
?.reversed(reverse)
is Sortation.ShiftDate -> list?.sortedWith(compareBy { it.second.shiftDate })
?.reversed(reverse)
is Sortation.units -> list?.sortedWith(compareBy { it.second.unitsCount })
?.reversed(reverse)
is Sortation.default -> viewModel.shiftData.value
}
}
private fun <T : Any> List<T>.reversed(b: Boolean): List<T> {
return apply {
if (b) reversed()
}
//
// return if (b) {
// this.reversed()
// } else {
// this
// }
}
fun filterShifts(op: Sortation, reverse: Boolean = false) {
selectSortation(op, reverse)
notifyDataSetChanged()
}
// override fun getFilter(): Filter {
// return object : Filter() {
// override fun performFiltering(constraint: CharSequence?): FilterResults {
//
//
// }
//
// override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
//
// }
// }
// }
}

View File

@@ -0,0 +1,51 @@
package com.appttude.h_mal.days_left.ui.main.list
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModel
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModelFactory
import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_shift_overview.*
import org.kodein.di.KodeinAware
import org.kodein.di.android.x.kodein
import org.kodein.di.generic.instance
class ShiftOverviewFragment : Fragment(), KodeinAware {
override val kodein by kodein()
private val factory by instance<ShiftsViewModelFactory>()
private val viewModel by viewModels<ShiftsViewModel> { factory }
lateinit var id: String
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
id = ShiftOverviewFragmentArgs.fromBundle(requireArguments()).id
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_shift_overview, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.getSingleShift(id).let {
val adapter = ShiftDetailsRecycler(requireContext(), it)
shift_details_recycler.adapter = adapter
}
edit_shift.setOnClickListener {
val action =
ShiftOverviewFragmentDirections.shiftOverviewToAddShiftActivity()
action.shiftId = id
view.navigateTo(action)
}
}
}

View File

@@ -0,0 +1,77 @@
package com.appttude.h_mal.days_left.ui.main.list
import android.content.Context
import androidx.appcompat.app.AlertDialog
import com.appttude.h_mal.days_left.data.prefs.PreferenceSource
import com.appttude.h_mal.days_left.ui.login.AuthViewModelFactory
import org.kodein.di.KodeinAware
import org.kodein.di.android.kodein
import org.kodein.di.generic.instance
class SortationDialog(
context: Context
): AlertDialog.Builder(context), KodeinAware{
override val kodein by kodein(context)
private val prefs by instance<PreferenceSource>()
val selectionPair = prefs.loadCurrentSortation()
private val groupName = arrayOf("Name", "Date Added", "Date of shift")
var checkedItem = selectionPair.second
// var sortation = ShiftListRecyclerAdapter.Sortation()
//
// init {
// setTitle("Sort by:")
// setSingleChoiceItems(groupName, checkedItem) { _, item ->
// checkedItem = item
// when (item) {
// 0 -> {
// sortation = ShiftListRecyclerAdapter.Sortation.Name()
// }
// 1 -> {
// sortation = ShiftListRecyclerAdapter.Sortation.DateAdded()
// fireAdapter.filterShifts(ShiftListRecyclerAdapter.Sortation.DateAdded())
// }
// 2 ->{
// fireAdapter.filterShifts(ShiftListRecyclerAdapter.Sortation.ShiftDate())
// }
// }
// }
// setPositiveButton("Ascending") { dialog, _ ->
//
// dialog.dismiss()
// }
// setNegativeButton("Descending") { dialog, _ ->
//
// dialog.dismiss()
// }
//
// create().show()
// }
//
// private fun sortData() {
//
//
// android.app.AlertDialog.Builder(context).apply {
// setTitle("Sort by:")
// setSingleChoiceItems(groupName, checkedItem) { dialog, item ->
// when (item) {
// 0 -> {
// fireAdapter.filterShifts(ShiftListRecyclerAdapter.Sortation.Name())
// }
// 1 -> {
// fireAdapter.filterShifts(ShiftListRecyclerAdapter.Sortation.DateAdded())
// }
// 2 ->{
// fireAdapter.filterShifts(ShiftListRecyclerAdapter.Sortation.ShiftDate())
// }
// }
// dialog.dismiss()
// }
// create().show()
// }
//
// }
}

View File

@@ -0,0 +1,226 @@
package com.appttude.h_mal.days_left.ui.main.shiftInfo
import android.content.Context
import android.content.DialogInterface
import android.graphics.Typeface
import android.os.Build
import android.view.View
import android.view.animation.AnimationUtils
import android.widget.EditText
import android.widget.TextView
import android.widget.TimePicker
import androidx.appcompat.app.AlertDialog
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.models.TimeObject
import kotlinx.android.synthetic.main.dialog_add_times.view.*
import java.util.*
class TimeDialog(
context: Context,
timeObject: TimeObject?,
val timeSelected: (TimeObject) -> Unit
): AlertDialog(context) {
val currentTimeObject = timeObject?.let {
if (it.timeIn.isNullOrEmpty()) return@let null
if (it.timeOut.isNullOrEmpty()) return@let null
it
} ?: TimeObject()
private var timePickerTimePicker: TimePicker? = null
private var startTimeTextView: TextView? = null
private var finishTimeTextView: TextView? = null
private var breakEditText: EditText? = null
private var currentTag: String? = null
private var breakInt: Int = 0
var timeSelect: View.OnClickListener = View.OnClickListener { v ->
currentTag = v.tag as String
val timeString: String?
if (currentTag == "start") {
timeString = currentTimeObject.timeIn?.takeIf { it.isNotBlank() }
toggleTextButtons(true)
} else {
timeString = currentTimeObject.timeOut?.takeIf { it.isNotBlank() }
toggleTextButtons(false)
}
if (timeString != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
timePickerTimePicker!!.hour = getTime(timeString)[0]
timePickerTimePicker!!.minute = getTime(timeString)[1]
}
} else {
val calendar = Calendar.getInstance()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
timePickerTimePicker!!.hour = calendar.get(Calendar.HOUR_OF_DAY)
timePickerTimePicker!!.minute = calendar.get(Calendar.MINUTE)
}
}
}
init {
val view = createView()
setView(view)
setNegativeButton()
setPositiveButton()
setButtonColour()
create()
show()
}
private fun createView(): View {
val view = View.inflate(context, R.layout.dialog_add_times, null)
currentTag = "start"
// instantiate views
startTimeTextView = view.from_date
finishTimeTextView = view.to_date
timePickerTimePicker = view.time_picker
breakEditText = view.breaktime
timePickerTimePicker!!.setIs24HourView(true)
initialiseTime()
currentTimeObject.breakInt?.toString()?.let {
breakEditText!!.setText(it)
}
startTimeTextView!!.tag = "start"
finishTimeTextView!!.tag = "finish"
startTimeTextView!!.setOnClickListener(timeSelect)
finishTimeTextView!!.setOnClickListener(timeSelect)
timePickerTimePicker!!.setOnTimeChangedListener { _, hourOfDay, minute ->
val ddTime = String.format("%02d", hourOfDay) + ":" + String.format("%02d", minute)
if (currentTag == "start") {
currentTimeObject!!.timeIn = ddTime
} else {
currentTimeObject!!.timeOut = ddTime
}
}
toggleTextButtons(true)
return view
}
private fun setNegativeButton(){
val text = context.getText(android.R.string.cancel)
setButton(DialogInterface.BUTTON_NEGATIVE, text) { _, _ ->
dismiss()
}
}
private fun setPositiveButton(){
val text = context.getText(android.R.string.ok)
setButton(DialogInterface.BUTTON_POSITIVE, text) { _, _ ->
if (currentTimeObject.timeIn != null &&
currentTimeObject.timeOut != null
) {
currentTimeObject.hours = calculateDuration() ?: return@setButton
currentTimeObject.breakInt = breakInt
timeSelected.invoke(currentTimeObject)
}
dismiss()
}
}
private fun setButtonColour(){
setOnShowListener {
val colour = context.resources.getColor(R.color.one)
getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(colour)
getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(colour)
}
}
private fun getTime(s: String): IntArray {
return intArrayOf(
Integer.parseInt(s.split(":".toRegex()).dropLastWhile { it.isEmpty() }
.toTypedArray()[0]),
Integer.parseInt(
s.split(
":".toRegex()
).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
)
)
}
private fun initialiseTime() {
val timeString = currentTimeObject.timeIn?.takeIf { it.isNotBlank() }
if (timeString != null) {
timePickerTimePicker!!.currentHour = getTime(timeString)[0]
timePickerTimePicker!!.currentMinute = getTime(timeString)[1]
} else {
val calendar = Calendar.getInstance()
timePickerTimePicker!!.currentHour = calendar.get(Calendar.HOUR_OF_DAY)
timePickerTimePicker!!.currentMinute = calendar.get(Calendar.MINUTE)
}
}
private fun calculateDuration(): Float? {
val startTime = currentTimeObject.timeIn?.takeIf { it.isNotBlank() } ?: return null
val finishTime = currentTimeObject.timeOut?.takeIf { it.isNotBlank() } ?: return null
breakInt = breakEditText?.text?.toString().takeIf { !it.isNullOrBlank() }?.toInt() ?: 0
val hoursIn = getTime(startTime)[0]
val hoursOut = getTime(finishTime)[0]
val minutesIn = getTime(startTime)[1]
val minutesOut = getTime(finishTime)[1]
val duration = if (hoursOut > hoursIn) {
hoursOut.toFloat() + minutesOut.toFloat() / 60 - (hoursIn.toFloat() + minutesIn.toFloat() / 60) - breakInt.toFloat() / 60
} else {
hoursOut.toFloat() + minutesOut.toFloat() / 60 - (hoursIn.toFloat() + minutesIn.toFloat() / 60) - breakInt.toFloat() / 60 + 24
}
val s = String.format("%.2f", duration)
return java.lang.Float.parseFloat(s)
}
private fun toggleTextButtons(top: Boolean) {
setFadeAnimation(startTimeTextView!!)
setFadeAnimation(finishTimeTextView!!)
if (top) {
startTimeTextView!!.setTypeface(null, Typeface.BOLD)
finishTimeTextView!!.setTypeface(null, Typeface.NORMAL)
startTimeTextView!!.setBackgroundColor(context.resources.getColor(android.R.color.white))
finishTimeTextView!!.setBackgroundColor(context.resources.getColor(R.color.one))
} else {
finishTimeTextView!!.setTypeface(null, Typeface.BOLD)
startTimeTextView!!.setTypeface(null, Typeface.NORMAL)
finishTimeTextView!!.setBackgroundColor(
context.resources.getColor(android.R.color.white)
)
startTimeTextView!!.setBackgroundColor(context.resources.getColor(R.color.one))
}
}
private fun setFadeAnimation(view: View) {
val bottomUp = AnimationUtils.loadAnimation(
context,
R.anim.fade_in
)
view.animation = bottomUp
}
}

View File

@@ -7,23 +7,25 @@ import android.content.pm.PackageManager
import android.os.Bundle
import android.os.Environment
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.ContextCompat.checkSelfPermission
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import com.appttude.h_mal.days_left.BuildConfig
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.utils.navigateTo
import com.appttude.h_mal.days_left.utils.safeFirebaseResult
import com.appttude.h_mal.days_left.utils.showToast
import com.google.android.gms.tasks.OnCompleteListener
import com.google.android.gms.tasks.Task
import com.google.firebase.functions.FirebaseFunctions
import com.google.firebase.functions.FirebaseFunctionsException
import com.google.firebase.storage.FirebaseStorage
import kotlinx.android.synthetic.main.fragment_tools.*
import java.io.File
import java.util.HashMap
import java.util.*
class FragmentTools : Fragment() {
@@ -43,15 +45,14 @@ class FragmentTools : Fragment() {
return inflater.inflate(R.layout.fragment_tools, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
compile.setOnClickListener(onClickListener)
summary_button.setOnClickListener(onClickListener)
}
internal val onClickListener = View.OnClickListener { view ->
private val onClickListener = View.OnClickListener { view ->
requestPermissions().let {
if (it) {
if (view.id == R.id.compile){
@@ -64,44 +65,33 @@ class FragmentTools : Fragment() {
}
internal val complete = OnCompleteListener<String>{task ->
if (!task.isSuccessful) {
val e = task.exception
if (e is FirebaseFunctionsException) {
val ffe = e as FirebaseFunctionsException?
val code = ffe!!.code
val details = ffe.details
}
Log.w(TAG, "addMessage:onFailure", e)
Toast.makeText(context, "An error occurred.", Toast.LENGTH_SHORT).show()
}else{
// [START_EXCLUDE]
val result = task.result as String
Log.i(TAG, "onComplete: $result")
val strings = result.split("/").toTypedArray()
val fbstore = storage.reference.child(result)
private val complete = OnCompleteListener<String>{ task ->
task.safeFirebaseResult({
val savePath = Environment.getExternalStorageDirectory().toString() + "/DaysLeftTemp"
val file = File(savePath)
if (!file.exists()) {
file.mkdirs()
}
it ?: return@safeFirebaseResult
val fbstore = storage.reference.child(it)
val strings = it.split("/").toTypedArray()
val myFile = File(savePath, strings.last())
fbstore.getFile(myFile).addOnSuccessListener {
fbstore.getFile(myFile).safeFirebaseResult({
// Local temp file has been created
val data =
FileProvider.getUriForFile(context!!, BuildConfig.APPLICATION_ID + ".provider", myFile)
FileProvider.getUriForFile(
requireContext(),
BuildConfig.APPLICATION_ID + ".provider",
myFile
)
activity?.grantUriPermission(
activity?.getPackageName(),
activity?.packageName,
data,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)
val intent1 = Intent(Intent.ACTION_VIEW)
.setDataAndType(data, "application/vnd.ms-excel")
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
@@ -109,16 +99,72 @@ class FragmentTools : Fragment() {
try {
activity?.startActivity(intent1)
} catch (e: ActivityNotFoundException) {
Toast.makeText(activity, "No Application Available to View Excel", Toast.LENGTH_SHORT)
.show()
context?.showToast("No Application Available to View Excel")
}
},{
},{
}.addOnFailureListener {
// Handle any errors
})
},{
context?.showToast(it)
},{
})
}
}
// if (!task.isSuccessful) {
//
//
// val e = task.exception
// if (e is FirebaseFunctionsException) {
// val ffe = e as FirebaseFunctionsException?
// val code = ffe!!.code
// val details = ffe.details
// }
//
// Log.w(TAG, "addMessage:onFailure", e)
// Toast.makeText(context, "An error occurred.", Toast.LENGTH_SHORT).show()
//
// }else{
// // [START_EXCLUDE]
//
// val result = task.result as String
// Log.i(TAG, "onComplete: $result")
//
// val strings = result.split("/").toTypedArray()
//
// val fbstore = storage.reference.child(result)
//
// val savePath = Environment.getExternalStorageDirectory().toString() + "/DaysLeftTemp"
// val file = File(savePath)
// if (!file.exists()) {
// file.mkdirs()
// }
//
// val myFile = File(savePath, strings.last())
//
// fbstore.getFile(myFile).addOnSuccessListener {
// // Local temp file has been created
// val data =
// FileProvider.getUriForFile(requireContext(), BuildConfig.APPLICATION_ID + ".provider", myFile)
// activity?.grantUriPermission(
// activity?.getPackageName(),
// data,
// Intent.FLAG_GRANT_READ_URI_PERMISSION
// )
// val intent1 = Intent(Intent.ACTION_VIEW)
// .setDataAndType(data, "application/vnd.ms-excel")
// .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
//
// try {
// activity?.startActivity(intent1)
// } catch (e: ActivityNotFoundException) {
// Toast.makeText(activity, "No Application Available to View Excel", Toast.LENGTH_SHORT)
// .show()
// }
//
//
// }
// }
}
fun writeToExcel(): Task<String> {
@@ -164,7 +210,7 @@ class FragmentTools : Fragment() {
}
fun requestPermissions() : Boolean{
if (checkSelfPermission(context!!, Manifest.permission.WRITE_EXTERNAL_STORAGE)
if (checkSelfPermission(requireContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Toast.makeText(context,"not granted",Toast.LENGTH_SHORT).show()

View File

@@ -0,0 +1,39 @@
package com.appttude.h_mal.days_left.ui.resultDialog
import android.content.Context
import android.content.DialogInterface
import android.view.View
import androidx.appcompat.app.AlertDialog
import com.appttude.h_mal.days_left.R
import kotlinx.android.synthetic.main.dialog_test_result.view.*
class ResultDialog(
context: Context,
result: Pair<Boolean, String?>,
callback: (() -> Unit)
): AlertDialog(context) {
init {
val layoutView = getView()
setView(layoutView)
setButton(DialogInterface.BUTTON_POSITIVE, "OK") { _, _ ->
callback()
}
setOnDismissListener {
callback()
}
create()
setViewDetails(layoutView, result)
show()
}
private fun getView(): View = View.inflate(context, R.layout.dialog_test_result, null)
private fun setViewDetails(dialogView: View, result: Pair<Boolean, String?>) {
val imageRes = if (result.first) {
R.mipmap.ic_success } else { R.mipmap.ic_failed }
dialogView.result_dialog_icon?.setImageResource(imageRes)
dialogView.result_dialog_text?.text = result.second
}
}

View File

@@ -0,0 +1,71 @@
package com.appttude.h_mal.days_left.ui.settings
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.login.AuthViewModel
import com.appttude.h_mal.days_left.utils.clearError
import com.appttude.h_mal.days_left.utils.showToast
import kotlinx.android.synthetic.main.fragment_change_email.*
class ChangeEmailFragment : Fragment() {
val viewModel by activityViewModels<AuthViewModel>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_change_email, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
submission_button.setOnClickListener {
viewModel.updateEmailAddress(
submission_et.text.toString(),
submission_email_again_et.text.toString(),
submission_password_et.text.toString()
)
}
viewModel.operationError.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let { res ->
context?.showToast(res)
// ResultDialog(requireContext(), res) {}
}
})
viewModel.updateForm.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let { form ->
form.emailError?.let { emailError ->
til_submission.error = getString(emailError)
}
form.newEmailError?.let { emailError ->
til_submission_email_again.error = getString(emailError)
}
form.passwordError?.let { passwordError ->
til_submission_password.error = getString(passwordError)
}
}
})
// submission_et.setOnClickListener(listener)
// submission_email_again_et.setOnClickListener(listener)
// submission_password_et.setOnClickListener(listener)
}
private val listener = View.OnClickListener {
til_submission.clearError()
til_submission_email_again.clearError()
til_submission_password.clearError()
}
}

View File

@@ -0,0 +1,20 @@
package com.appttude.h_mal.days_left.ui.settings
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.appttude.h_mal.days_left.R
class ChangeNameFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_change_name, container, false)
}
}

View File

@@ -0,0 +1,70 @@
package com.appttude.h_mal.days_left.ui.settings
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.login.AuthViewModel
import com.appttude.h_mal.days_left.utils.clearError
import com.appttude.h_mal.days_left.utils.showToast
import kotlinx.android.synthetic.main.fragment_change_password.*
class ChangePasswordFragment : Fragment() {
val viewModel by activityViewModels<AuthViewModel>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_change_password, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
submission_button.setOnClickListener {
viewModel.updateEmailAddress(
submission_et.text.toString(),
submission_password_et.text.toString(),
submission_password_again_et.text.toString()
)
}
viewModel.operationError.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let { res ->
context?.showToast(res)
// ResultDialog(requireContext(), res) {}
}
})
viewModel.updateForm.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let { form ->
form.emailError?.let { emailError ->
til_submission.error = getString(emailError)
}
form.passwordError?.let { passwordError ->
til_submission_password.error = getString(passwordError)
}
form.newPasswordError?.let { passwordError ->
til_submission_password_again.error = getString(passwordError)
}
}
})
submission_et.setOnClickListener(listener)
submission_password_et.setOnClickListener(listener)
submission_password_again_et.setOnClickListener(listener)
}
private val listener = View.OnClickListener {
til_submission.clearError()
til_submission_password.clearError()
til_submission_password_again.clearError()
}
}

View File

@@ -0,0 +1,43 @@
package com.appttude.h_mal.days_left.ui.settings
import android.os.Bundle
import androidx.fragment.app.activityViewModels
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.login.AuthViewModel
import com.appttude.h_mal.days_left.ui.main.MainViewModel
import com.appttude.h_mal.days_left.utils.navigateTo
class SettingsFragment : PreferenceFragmentCompat() {
val viewModel by activityViewModels<AuthViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
findPreference<Preference>("email")?.setOnPreferenceClickListener {
view?.navigateTo(R.id.to_changeEmailFragment)
true
}
findPreference<Preference>("password")?.setOnPreferenceClickListener {
view?.navigateTo(R.id.to_changePasswordFragment)
true
}
findPreference<Preference>("name")?.setOnPreferenceClickListener {
view?.navigateTo(R.id.to_changeNameFragment)
true
}
findPreference<Preference>("log_out")?.setOnPreferenceClickListener {
viewModel.logout()
view?.navigateTo(R.id.mainTo_loginHomeFragment)
activity?.finish()
true
}
}
}

View File

@@ -0,0 +1,50 @@
package com.appttude.h_mal.days_left.utils
import com.google.android.gms.tasks.Task
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.ValueEventListener
import java.io.IOException
fun <T : Any> Task<T?>.safeFirebaseResult(): T? {
if (!isSuccessful) {
throw exception ?: IOException("Failed to complete firebase task")
} else {
return result!!
}
}
fun <T : Any> Task<T>.safeFirebaseResult(
success: ((T?) -> Unit),
failure: ((String) -> Unit),
complete: (() -> Unit)
){
this.addOnSuccessListener {
success(it)
complete()
}.addOnFailureListener {
it.printStackTrace()
failure(it.message!!)
complete()
}
}
fun Exception.firebaseError(): String?{
cause?.printStackTrace()
return message
}
fun DatabaseReference.getResults(
result: ((DataSnapshot?) -> Unit)
){
addListenerForSingleValueEvent(object : ValueEventListener{
override fun onCancelled(error: DatabaseError) {
result.invoke(null)
}
override fun onDataChange(snapshot: DataSnapshot) {
result.invoke(snapshot)
}
})
}

View File

@@ -0,0 +1,10 @@
package com.appttude.h_mal.days_left.utils
fun Double.formatToTwoDp() = String.format("%.2f", this)
fun Float.formatToTwoDp() = String.format("%.2f", this)
fun Int.formatDateInt(): String = String.format("%02d", this)
fun getTimeString(hourOfDay: Int, minute: Int): String{
return String.format("%02d", hourOfDay) + ":" + String.format("%02d", minute)
}

View File

@@ -0,0 +1,24 @@
package com.appttude.h_mal.days_left.utils
open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
}

View File

@@ -0,0 +1,12 @@
package com.appttude.h_mal.days_left.utils
import androidx.lifecycle.ViewModel
import com.google.gson.Gson
abstract class ObjectSerializer {
val gson by lazy { Gson() }
fun Any.serialiseToString(): String? {
return gson.toJson(this)
}
}

View File

@@ -0,0 +1,19 @@
package com.appttude.h_mal.days_left.utils
import android.content.Context
import androidx.core.content.res.ResourcesCompat
const val PIECE_CONST = "Piece Rate"
const val HOURLY_CONST = "Hourly"
const val UID = "uid"
const val USER_FIREBASE = "users"
const val EMPLOYER_FIREBASE = "employers"
const val SHIFT_FIREBASE = "shifts"
const val ABN_FIREBASE = "abn"
const val RECENT_EMPLOYERS = "recentemployers"
const val TASK_LIST = "taskList"
fun Context.loadColour(id: Int): Int {
return ResourcesCompat.getColor(resources, id,null)
}

View File

@@ -1,6 +1,5 @@
package com.appttude.h_mal.days_left.utils
import android.text.TextUtils
import java.util.regex.Pattern
// Password must contain 8-16 characters,
@@ -13,9 +12,12 @@ fun isPasswordValid(password: String?): Boolean {
}
fun isNameValid(name: String?): Boolean {
return name?.let {
Pattern.compile("[a-zA-Z]{4,}(?: [a-zA-Z]+){0,2}\$").matcher(it).find()
} ?: false
return !name.isNullOrBlank()
// return name?.let {
//// [a-zA-Z]{4,}(?: [a-zA-Z]+){0,2}$
// Pattern.compile("[a-zA-Z]{4,}(?: [a-zA-Z]+){0,2}\$").matcher(it).find()
// } ?: false
}
fun isEmailValid(email: String?): Boolean {

View File

@@ -2,26 +2,39 @@ package com.appttude.h_mal.days_left.utils
import android.app.Activity
import android.content.Context
import android.net.Uri
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.ImageView
import android.widget.Toast
import androidx.annotation.StringRes
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.navigation.NavDirections
import androidx.navigation.Navigation
import com.squareup.picasso.Picasso
import java.lang.Exception
import androidx.navigation.findNavController
import com.appttude.h_mal.days_left.R
import com.google.android.material.textfield.TextInputLayout
fun View.show() {
this.visibility = View.VISIBLE
visibility = View.VISIBLE
}
fun View.hide() {
this.visibility = View.GONE
visibility = View.GONE
}
fun View.setVis(b: Boolean) {
if (b){ show() }else{ hide() }
}
fun View.toggleVisibility() {
if (isVisible){ hide() }else{ show() }
}
fun Context.showToast(message: String) {
@@ -32,36 +45,72 @@ fun Context.showToast(@StringRes resourceId: Int) {
Toast.makeText(this, resourceId, Toast.LENGTH_LONG).show()
}
fun Context.hideKeyboard(view: View?) {
val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(view?.windowToken, 0)
fun View.hideKeyboard() {
val inputMethodManager =
context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
}
fun View.navigateTo(navigationId: Int) {
try {
Navigation.findNavController(this).navigate(navigationId)
}catch (e: IllegalArgumentException){
e.printStackTrace()
}
findNavController().navigate(navigationId)
}
fun View.navigateTo(navDirections: NavDirections) {
Navigation.findNavController(this).navigate(navDirections)
}
fun View.popBack(){
Navigation.findNavController(this).popBackStack()
}
fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
this.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(editable: Editable?) {
afterTextChanged.invoke(editable.toString())
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
}
fun View.layoutListener(work: (() -> Unit)) {
this.viewTreeObserver.addOnGlobalLayoutListener(object :
ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
work()
this@layoutListener.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})
}
fun Context.inflateLayout(id: Int): View {
return LayoutInflater
.from(this)
.inflate(id, null)
}
fun Context.inflateLayout(id: Int, parent: ViewGroup): View {
return LayoutInflater
.from(this)
.inflate(id, parent, false)
}
fun TextInputLayout.clearError(){
error = null
}
fun FragmentActivity.navigateTo(f: Fragment){
supportFragmentManager
.beginTransaction()
.replace(
R.id.container,
f
).commit()
}
//fun ImageView.setPicassoIcon(profileUrl: String?) {
// val width = layoutParams?.width?.takeIf { it > 0 }
// val height = layoutParams?.height?.takeIf { it > 0 }

View File

@@ -3,3 +3,5 @@ package com.appttude.h_mal.days_left.utils
import com.google.gson.reflect.TypeToken
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M19.1,12.9a2.8,2.8 0,0 0,0.1 -0.9,2.8 2.8,0 0,0 -0.1,-0.9l2.1,-1.6a0.7,0.7 0,0 0,0.1 -0.6L19.4,5.5a0.7,0.7 0,0 0,-0.6 -0.2l-2.4,1a6.5,6.5 0,0 0,-1.6 -0.9l-0.4,-2.6a0.5,0.5 0,0 0,-0.5 -0.4H10.1a0.5,0.5 0,0 0,-0.5 0.4L9.3,5.4a5.6,5.6 0,0 0,-1.7 0.9l-2.4,-1a0.4,0.4 0,0 0,-0.5 0.2l-2,3.4c-0.1,0.2 0,0.4 0.2,0.6l2,1.6a2.8,2.8 0,0 0,-0.1 0.9,2.8 2.8,0 0,0 0.1,0.9L2.8,14.5a0.7,0.7 0,0 0,-0.1 0.6l1.9,3.4a0.7,0.7 0,0 0,0.6 0.2l2.4,-1a6.5,6.5 0,0 0,1.6 0.9l0.4,2.6a0.5,0.5 0,0 0,0.5 0.4h3.8a0.5,0.5 0,0 0,0.5 -0.4l0.3,-2.6a5.6,5.6 0,0 0,1.7 -0.9l2.4,1a0.4,0.4 0,0 0,0.5 -0.2l2,-3.4c0.1,-0.2 0,-0.4 -0.2,-0.6ZM12,15.6A3.6,3.6 0,1 1,15.6 12,3.6 3.6,0 0,1 12,15.6Z"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,3h-4.18C14.4,1.84 13.3,1 12,1c-1.3,0 -2.4,0.84 -2.82,2L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM12,3c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM14,17L7,17v-2h7v2zM17,13L7,13v-2h10v2zM17,9L7,9L7,7h10v2z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M11.8,10.9c-2.27,-0.59 -3,-1.2 -3,-2.15 0,-1.09 1.01,-1.85 2.7,-1.85 1.78,0 2.44,0.85 2.5,2.1h2.21c-0.07,-1.72 -1.12,-3.3 -3.21,-3.81V3h-3v2.16c-1.94,0.42 -3.5,1.68 -3.5,3.61 0,2.31 1.91,3.46 4.7,4.13 2.5,0.6 3,1.48 3,2.41 0,0.69 -0.49,1.79 -2.7,1.79 -2.06,0 -2.87,-0.92 -2.98,-2.1h-2.2c0.12,2.19 1.76,3.42 3.68,3.83V21h3v-2.15c1.95,-0.37 3.5,-1.5 3.5,-3.55 0,-2.84 -2.43,-3.81 -4.7,-4.4z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
</vector>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:background="@color/colorInvalid"
android:layout_width="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_height="1dp"/>
<TextView
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:id="@+id/title"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearancePopupMenuHeader"
android:gravity="center_vertical"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
tools:text="Title"/>
</LinearLayout>

View File

@@ -1,92 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="6dp"
android:layout_marginRight="12dp"
android:layout_marginBottom="6dp"
app:cardCornerRadius="@dimen/card_radius">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/farm_name"
style="@style/title_card"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:includeFontPadding="false"
android:textColor="@color/three"
tools:text="W and L farms" />
</LinearLayout>
<LinearLayout
android:id="@+id/text_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<TextView
style="@style/text_major"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="left|center"
android:text="ABN : " />
<TextView
android:id="@+id/abn_text"
style="@style/text_minor"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
tools:text="75642358411" />
</LinearLayout>
<LinearLayout
android:id="@+id/text_holder_two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
style="@style/text_major"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="left|center"
android:text="Postcode : " />
<TextView
android:id="@+id/postcode_text"
style="@style/text_minor"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:text="QLD 4670" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>

View File

@@ -1,291 +1,61 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.addShift.AddShiftActivity">
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".AddItems.AddEmployerFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_alignParentTop="true"
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/AppTheme.AppBarOverlay"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"
tools:title="@string/app_name">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="@+id/container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="@id/appbar"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/appbar"
app:navGraph="@navigation/add_shift_navigation"
tools:context=".ui.addShift.AddShiftActivity"/>
<ProgressBar
android:id="@+id/progressBar2"
style="?android:attr/progressBarStyle"
android:visibility="gone"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progress_bar"
android:visibility="gone"/>
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true"
android:id="@+id/centre_view">
<androidx.cardview.widget.CardView
android:id="@+id/select_employer_card"
style="@style/cardview_theme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16sp"
app:cardBackgroundColor="@color/two">
<LinearLayout
android:id="@+id/employer_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/cardviewoutline"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:visibility="gone">
<TextView
android:id="@+id/employer_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:alpha="0.65"
android:textColor="@color/one"
android:textSize="20sp"
android:textStyle="bold"
tools:text="W and L farms" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:alpha="0.56"
android:src="@drawable/marker" />
<TextView
android:id="@+id/employer_location"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
tools:text="Bundaberg" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/lable_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:text="Select Employer"
android:textSize="18sp" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/select_task_card"
style="@style/cardview_theme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16sp"
app:cardBackgroundColor="@color/two">
<LinearLayout
android:id="@+id/task_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/cardviewoutline"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:visibility="gone">
<TextView
android:id="@+id/task"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:alpha="0.65"
android:textColor="@color/three"
android:textSize="16sp"
tools:text="Packing Tomatoes" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:alpha="0.56"
android:src="@drawable/task" />
<TextView
android:id="@+id/task_summary"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
tools:text="Bundaberg" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/lable_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:text="Select Task"
android:textSize="18sp" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/select_times_card"
style="@style/cardview_theme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16sp"
app:cardBackgroundColor="@color/two">
<LinearLayout
android:id="@+id/time_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/cardviewoutline"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:visibility="gone">
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:alpha="0.65"
android:textColor="@color/three"
android:textSize="16sp"
tools:text="11H 30m" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:alpha="0.56"
android:src="@drawable/clock_icon" />
<TextView
android:id="@+id/time_summary"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
tools:text="11:30 - 18:30" />
</LinearLayout>
<LinearLayout
android:id="@+id/break_holder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:alpha="0.56"
android:src="@drawable/break_time" />
<TextView
android:id="@+id/break_summary"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
tools:text="30 minutes" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/lable_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:text="insert times"
android:textSize="18sp"
android:visibility="visible" />
</androidx.cardview.widget.CardView>
<EditText
android:id="@+id/units"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:background="@drawable/round_edit_text"
android:hint="Insert units/time"
android:inputType="numberDecimal"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:selectAllOnFocus="true"
android:textColorHighlight="#608d91" />
<EditText
android:id="@+id/date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/round_edit_text"
android:hint="Select date"
android:inputType="numberDecimal"
android:focusable="false"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:selectAllOnFocus="true"
android:textColorHighlight="#608d91" />
</LinearLayout>
<ImageButton
android:id="@+id/search_button"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:background="@drawable/yes_button"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:scaleType="fitCenter"
android:src="@drawable/checkmark"
android:tint="#2b452d" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
android:orientation="vertical"
tools:context=".Login.ChangeUserDetailsActivity">
android:orientation="vertical">
<LinearLayout
android:id="@+id/ph_view_holder"

View File

@@ -32,26 +32,19 @@
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
<fragment
android:layout_below="@id/appbar"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_above="@id/navigation"
app:defaultNavHost="true"
app:navGraph="@navigation/main_navigation"
android:name="androidx.navigation.fragment.NavHostFragment"
app:layout_constraintBottom_toTopOf="@id/navigation"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/appbar"
android:id="@+id/container">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_input_add"
android:tint="@android:color/white" />
</FrameLayout>
android:id="@+id/container"/>
<ProgressBar
android:id="@+id/progressBar2"
@@ -66,13 +59,12 @@
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="?android:attr/windowBackground"
app:menu="@menu/navigation"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/navigation"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">

View File

@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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">
@@ -20,12 +18,6 @@
android:gravity="center"
android:text="Start" />
<!--<ImageView-->
<!--android:layout_width="1dp"-->
<!--android:background="#8aa4bf"-->
<!--android:layout_height="match_parent"-->
<!--android:layout_margin="4dp"/>-->
<TextView
android:id="@+id/to_date"
android:layout_width="0dp"
@@ -45,47 +37,27 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:headerBackground="@color/colorPrimaryDark"
android:numbersSelectorColor="@color/colorPrimary">
android:numbersSelectorColor="@color/colorPrimary"
android:timePickerMode="spinner">
<LinearLayout
</TimePicker>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="right|bottom">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom">
android:text="Break (in minutes) : " />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Break (in minutes) : " />
<EditText
android:id="@+id/breaktime"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:inputType="number" />
</LinearLayout>
</TimePicker>
</LinearLayout>
<LinearLayout
android:id="@+id/end"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="0dp"
android:layout_height="@android:dimen/app_icon_size"
android:layout_weight="2" />
<TextView
android:id="@+id/ok"
android:layout_width="0dp"
android:layout_height="@android:dimen/app_icon_size"
android:layout_weight="1"
android:gravity="center"
android:text="OK"
android:textColor="@color/colorPrimaryDark"
android:textStyle="bold" />
<EditText
android:id="@+id/breaktime"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:inputType="number"
android:text="0"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".AddItems.AddEmployerFragment">
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="16dp">
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.5"/>
<ImageView
android:id="@+id/result_dialog_icon"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:adjustViewBounds="true"
android:src="@mipmap/ic_failed" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.5"/>
</LinearLayout>
<TextView
android:id="@+id/result_dialog_text"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:gravity="center"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearancePopupMenuHeader"
tools:text="Sample scanned successfully" />
</LinearLayout>

View File

@@ -5,67 +5,28 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".AddItemActivity">
tools:context=".ui.addShift.AddEmployerFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/searched_abn_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="@+id/spinning_pb"
android:id="@+id/searched_abn_progbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<LinearLayout
android:id="@+id/empty_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/marker" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/empty_line_one"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/empty_line_two"
android:textSize="16sp" />
</LinearLayout>
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,291 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="ui.addShift.AddShiftFragment">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progress_bar"
android:visibility="gone"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true"
android:id="@+id/centre_view">
<androidx.cardview.widget.CardView
android:id="@+id/select_employer_card"
style="@style/cardview_theme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16sp"
app:cardBackgroundColor="@color/two">
<LinearLayout
android:id="@+id/employer_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/cardviewoutline"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:visibility="gone">
<TextView
android:id="@+id/employer_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:alpha="0.65"
android:textColor="@color/one"
android:textSize="20sp"
android:textStyle="bold"
tools:text="W and L farms" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:alpha="0.56"
android:src="@drawable/marker" />
<TextView
android:id="@+id/employer_location"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
tools:text="Bundaberg" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/lable_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:text="Select Employer"
android:textSize="18sp" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/select_task_card"
style="@style/cardview_theme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16sp"
app:cardBackgroundColor="@color/two">
<LinearLayout
android:id="@+id/task_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/cardviewoutline"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:visibility="gone">
<TextView
android:id="@+id/task"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:alpha="0.65"
android:textColor="@color/three"
android:textSize="16sp"
tools:text="Packing Tomatoes" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:alpha="0.56"
android:src="@drawable/task" />
<TextView
android:id="@+id/task_summary"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
tools:text="Bundaberg" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/lable_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:text="Select Task"
android:textSize="18sp" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/select_times_card"
style="@style/cardview_theme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16sp"
app:cardBackgroundColor="@color/two">
<LinearLayout
android:id="@+id/time_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/cardviewoutline"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:visibility="gone">
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:alpha="0.65"
android:textColor="@color/three"
android:textSize="16sp"
tools:text="11H 30m" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:alpha="0.56"
android:src="@drawable/clock_icon" />
<TextView
android:id="@+id/time_summary"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
tools:text="11:30 - 18:30" />
</LinearLayout>
<LinearLayout
android:id="@+id/break_holder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:alpha="0.56"
android:src="@drawable/break_time" />
<TextView
android:id="@+id/break_summary"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
tools:text="30 minutes" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/lable_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:text="insert times"
android:textSize="18sp"
android:visibility="visible" />
</androidx.cardview.widget.CardView>
<EditText
android:id="@+id/units"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:background="@drawable/round_edit_text"
android:hint="Insert units/time"
android:inputType="numberDecimal"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:selectAllOnFocus="true"
android:textColorHighlight="#608d91" />
<EditText
android:id="@+id/date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/round_edit_text"
android:hint="Select date"
android:inputType="numberDecimal"
android:focusable="false"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp"
android:selectAllOnFocus="true"
android:textColorHighlight="#608d91" />
</LinearLayout>
<ImageButton
android:id="@+id/search_button"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:background="@drawable/yes_button"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:scaleType="fitCenter"
android:src="@drawable/checkmark"
android:tint="#2b452d" />
</RelativeLayout>

View File

@@ -1,7 +1,6 @@
<?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="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"

View File

@@ -0,0 +1,118 @@
<?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"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/submission_title_tv"
style="@style/title_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:text="@string/change_email_title"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.15" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_submission"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/submission_title_tv">
<EditText
android:id="@+id/submission_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textEmailAddress"
android:selectAllOnFocus="true"
android:hint="Enter existing email address"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_submission_email_again"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_submission">
<EditText
android:id="@+id/submission_email_again_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textEmailAddress"
android:hint="Enter new email address"
android:maxLines="1"
android:selectAllOnFocus="true"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_submission_password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_submission_email_again">
<EditText
android:id="@+id/submission_password_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textWebPassword"
android:hint="Enter Password"
android:maxLines="1"
android:selectAllOnFocus="true"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.cardview.widget.CardView
android:id="@+id/submission_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="64dp"
android:backgroundTint="@color/two"
android:enabled="false"
app:cardCornerRadius="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_submission_password"
app:layout_constraintVertical_bias="0.2">
<TextView
android:id="@+id/submission_button_label"
style="@style/button_inner_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/submit"
android:textColor="@android:color/white" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,73 @@
<?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"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/submission_title_tv"
style="@style/title_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:text="@string/change_name_title"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.2" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_submission"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/submission_title_tv">
<EditText
android:enabled="false"
android:id="@+id/submission_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textEmailAddress"
android:hint="Enter new name"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.cardview.widget.CardView
android:id="@+id/submission_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="64dp"
android:backgroundTint="@color/two"
app:cardCornerRadius="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_submission"
app:layout_constraintVertical_bias="0.2">
<TextView
android:id="@+id/submission_button_label"
style="@style/button_inner_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/submit"
android:textColor="@android:color/white" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,114 @@
<?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"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/submission_title_tv"
style="@style/title_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:text="@string/change_password_title"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.15" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_submission"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/submission_title_tv">
<EditText
android:id="@+id/submission_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textEmailAddress"
android:hint="Enter Email address"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_submission_password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_submission">
<EditText
android:id="@+id/submission_password_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textWebPassword"
android:hint="Enter Password"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_submission_password_again"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_submission_password">
<EditText
android:id="@+id/submission_password_again_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textWebPassword"
android:hint="Enter new Password"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.cardview.widget.CardView
android:id="@+id/submission_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="64dp"
android:backgroundTint="@color/two"
app:cardCornerRadius="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_submission_password_again"
app:layout_constraintVertical_bias="0.2">
<TextView
android:id="@+id/submission_button_label"
style="@style/button_inner_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/submit"
android:textColor="@android:color/white" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ui.addShift.EmployersFragment">
<LinearLayout
android:id="@+id/top_container"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:orientation="horizontal"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<TextView
android:id="@+id/top_label"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
style="@style/test_item_title"
android:text="Add Employer"
android:textAppearance="@style/title_text"/>
<ImageView
android:id="@+id/add_test"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:tint="@android:color/black"
android:layout_margin="6dp"
android:src="@drawable/ic_baseline_add_circle_24"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/employer_recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_container"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/general_list_item"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,15 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.appttude.h_mal.days_left.ui.main.list.FragmentList">
<ListView
android:id="@+id/page_two_list"
<LinearLayout
android:id="@+id/top_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:orientation="horizontal"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<TextView
android:id="@+id/top_label"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
style="@style/test_item_title"
android:text="Add Shift"
android:textAppearance="@style/title_text"/>
<ImageView
android:id="@+id/add_test"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:tint="@android:color/black"
android:layout_margin="6dp"
android:elevation="4dp"
android:src="@drawable/ic_baseline_add_circle_24"/>
</LinearLayout>
</ListView>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_container">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:background="@color/dimGrey"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/list_item"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -23,7 +23,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="Enter Your Password" />
android:text="Enter Your Password Again" />
<TextView
android:id="@+id/submission_subtitle_tv"

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ui.main.list.ShiftOverviewFragment">
<LinearLayout
android:id="@+id/top_container"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:orientation="horizontal"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<TextView
android:id="@+id/top_label"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
style="@style/test_item_title"
android:text="Edit Shift"
android:textAppearance="@style/title_text"/>
<ImageView
android:id="@+id/edit_shift"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:tint="@android:color/black"
android:layout_margin="6dp"
android:src="@drawable/ic_baseline_edit_24"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/shift_details_recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toBottomOf="@id/top_container"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.appttude.h_mal.days_left.ui.addShift.TasksFragment">
<LinearLayout
android:id="@+id/top_container"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:orientation="horizontal"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<TextView
android:id="@+id/top_label"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
style="@style/test_item_title"
android:text="Add Task"
android:textAppearance="@style/title_text"/>
<ImageView
android:id="@+id/add_test"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:tint="@android:color/black"
android:layout_margin="6dp"
android:src="@drawable/ic_baseline_add_circle_24"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tasks_recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_container"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/task_list_item"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
app:cardCornerRadius="@dimen/card_radius">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:orientation="vertical">
<TextView
android:id="@+id/item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:singleLine="true"
android:textColor="@color/one"
android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
tools:text="W and L Farm" />
<include
android:id="@+id/location_layout"
layout="@layout/icon_text_layout"/>
<include
android:id="@+id/abn_layout"
layout="@layout/icon_text_layout"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"
tools:listitem="@layout/item_three"
android:id="@+id/grid_layout">
</androidx.recyclerview.widget.RecyclerView>

View File

@@ -0,0 +1,64 @@
<?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:background="?android:attr/selectableItemBackground"
android:baselineAligned="false"
android:orientation="horizontal"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingRight="?android:attr/listPreferredItemPaddingRight">
<FrameLayout
android:id="@+id/image_icon"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="@id/text_container"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="@id/text_container">
<ImageView
android:id="@+id/icon"
android:layout_gravity="center"
android:layout_height="24dp"
android:layout_marginRight="0dp"
style="@style/container_icon"
tools:src="@drawable/ic_baseline_edit_24"/>
</FrameLayout>
<LinearLayout
android:id="@+id/text_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
style="@style/container"
app:layout_constraintLeft_toRightOf="@id/image_icon"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/two"
android:alpha="0.85"
tools:text="asdasdas" />
<TextView
android:id="@+id/item_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="web"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
tools:text="asdasdas" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:id="@+id/empty_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/marker" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/empty_line_one"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/empty_line_two"
android:textSize="16sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,20 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintWidth_percent="0.5"
android:layout_marginLeft="12dp"
android:layout_marginTop="6dp"
android:layout_marginRight="12dp"
android:layout_marginBottom="6dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:cardCornerRadius="@dimen/card_radius">
<FrameLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp">
@@ -22,13 +29,24 @@
<com.appttude.h_mal.days_left.ui.customViews.CircleView
android:id="@+id/arc_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
android:layout_height="wrap_content"
android:layout_gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
tools:circle_thickness="20"
tools:circle_arc="340"
custom:arc_colour="@color/one"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:orientation="vertical">
<LinearLayout
@@ -70,9 +88,9 @@
android:textColor="@color/one"
android:textSize="16sp" />
</LinearLayout>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -10,17 +11,23 @@
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="6dp"
android:layout_marginRight="12dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="6dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:cardCornerRadius="@dimen/card_radius">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="6dp"
android:orientation="vertical">
<LinearLayout
android:id="@+id/header_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
@@ -30,72 +37,80 @@
android:layout_width="30dp"
android:layout_height="30dp"
android:alpha="0.45"
android:layout_gravity="center"
android:src="@drawable/clock_icon"
app:layout_constraintDimensionRatio="1:1" />
<TextView
android:id="@+id/card_title"
style="@style/title_card"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="6dp"
android:gravity="center_vertical"
android:includeFontPadding="false"
android:textColor="@color/three"
tools:text="Hourly" />
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:singleLine="true"
android:maxLines="2"
android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
android:gravity="center_vertical"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:layout_width="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:layout_height="wrap_content"
tools:text="Title"/>
</LinearLayout>
<LinearLayout
android:id="@+id/text_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
style="@style/container_main">
<TextView
style="@style/text_major"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="left|center"
android:text="Total : " />
<TextView android:id="@+id/title_one_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
android:ellipsize="marquee"
android:text="Total"/>
<TextView
android:id="@+id/units"
style="@style/text_minor"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:text="296 Hours" />
<TextView android:id="@+id/units"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:autoLink="web"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="296 Hours"/>
</LinearLayout>
<LinearLayout
android:id="@+id/text_holder_two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
style="@style/container_main">
<TextView
style="@style/text_major"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="left|center"
android:text="Earned : " />
<TextView android:id="@+id/title_two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
android:ellipsize="marquee"
android:text="Earned"/>
<TextView
android:id="@+id/total_earned"
style="@style/text_minor"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:text="$965.37" />
<TextView android:id="@+id/total_earned"
android:layout_alignLeft="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:autoLink="web"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="$965.37"/>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -13,114 +13,89 @@
android:layout_marginBottom="6dp"
app:cardCornerRadius="@dimen/card_radius">
<LinearLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/lin"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:orientation="vertical">
<!--<LinearLayout-->
<!--android:id="@+id/text_holder"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:orientation="horizontal">-->
<!--<TextView-->
<!--style="@style/text_major"-->
<!--android:layout_width="0dp"-->
<!--android:layout_height="match_parent"-->
<!--android:layout_weight="1"-->
<!--android:gravity="left|center"-->
<!--android:text="Piece" />-->
<!--<TextView-->
<!--style="@style/text_major"-->
<!--android:layout_width="0dp"-->
<!--android:layout_height="match_parent"-->
<!--android:layout_weight="1"-->
<!--android:gravity="right|center"-->
<!--android:text="Hourly" />-->
<!--</LinearLayout>-->
android:layout_height="wrap_content"
android:padding="16dp">
<com.appttude.h_mal.days_left.ui.customViews.BarView
android:id="@+id/bar"
android:layout_width="match_parent"
android:layout_height="80dp" />
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_height="6dp" />
<!--<LinearLayout-->
<!--android:id="@+id/bottom_text_holder"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:orientation="horizontal">-->
<!--<TextView-->
<!--style="@style/text_minor"-->
<!--android:layout_width="0dp"-->
<!--android:layout_height="match_parent"-->
<!--android:layout_weight="1"-->
<!--android:gravity="left|center"-->
<!--android:text="43" />-->
<!--<TextView-->
<!--style="@style/text_minor"-->
<!--android:layout_width="0dp"-->
<!--android:layout_height="match_parent"-->
<!--android:layout_weight="1"-->
<!--android:gravity="right|center"-->
<!--android:text="33" />-->
<!--</LinearLayout>-->
<LinearLayout
android:id="@+id/bottom_text_holder_one"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@id/bar"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<TextView
style="@style/text_major"
android:layout_width="0dp"
android:id="@+id/text_piece_header"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:gravity="left"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:text="Piece Rate" />
<TextView
android:id="@+id/pc_amount_text"
style="@style/text_minor"
android:layout_width="0dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:text="43" />
<View
android:layout_width="10dp"
android:layout_height="2dp"
android:layout_gravity="center"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:background="@color/two" />
<TextView
android:id="@+id/hr_amount_text"
style="@style/text_minor"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="33" />
<TextView
style="@style/text_major"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:gravity="right"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/text_piece_header"
android:text="Hourly" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/bottom_text_holder_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/text_piece_header"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="@id/text_piece_header"
android:orientation="horizontal">
<TextView
android:id="@+id/pc_amount_text"
style="@style/text_minor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:maxLines="1"
android:text="43" />
<View
android:layout_width="10dp"
android:layout_height="2dp"
android:layout_gravity="center"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:background="@color/two" />
<TextView
android:id="@+id/hr_amount_text"
style="@style/text_minor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="33" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingRight="?android:attr/listPreferredItemPaddingRight"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/selectableItemBackground"
android:baselineAligned="false"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:orientation="vertical">
<TextView android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
android:ellipsize="marquee"
tools:text="asdasdas"/>
<TextView android:id="@android:id/text2"
android:layout_alignLeft="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:autoLink="web"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="asdasdas"/>
</LinearLayout>

View File

@@ -1,175 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout
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"
xmlns:tools="http://schemas.android.com/tools">
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="6dp"
android:layout_marginRight="12dp"
android:layout_marginBottom="6dp"
app:cardCornerRadius="@dimen/card_radius">
<LinearLayout
android:elevation="0dp"
android:layout_margin="12dp"
app:cardCornerRadius="@dimen/card_radius"
tools:cardBackgroundColor="#BDBDBD" >
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:orientation="vertical">
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<LinearLayout
android:id="@+id/container_one"
style="@style/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="6dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/farm_name"
style="@style/title_card"
android:id="@+id/item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="marquee"
android:singleLine="true"
android:textColor="@color/one"
android:textSize="22sp"
android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
tools:text="W and L Farm" />
<TextView
android:id="@+id/task_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="left|center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="web"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/two"
android:textSize="20sp"
tools:text="Packing Tomatoes" />
</LinearLayout>
<TextView
android:id="@+id/date"
style="@style/text_major"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:gravity="top|right"
android:textColor="@color/two"
android:alpha="0.7"
android:textSize="12sp"
tools:text="19/04/2018" />
</LinearLayout>
<LinearLayout
android:id="@+id/container_two"
style="@style/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp">
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/container_one">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:alpha="0.45"
style="@style/container_icon"
android:src="@drawable/task" />
<TextView
android:id="@+id/type"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:gravity="center_vertical"
android:textSize="18sp"
style="@style/container_subtext"
tools:text="Hourly - $23/Hour" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:id="@+id/container_three"
style="@style/container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/time_holder">
android:elevation="3dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/container_two"
app:layout_constraintWidth_percent="0.5">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:alpha="0.45"
style="@style/container_icon"
android:src="@drawable/clock_icon" />
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:gravity="center_vertical"
android:textSize="18sp"
tools:text="10:00 - 18:00" />
<LinearLayout
android:id="@+id/break_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:alpha="0.45"
android:src="@drawable/break_time" />
<TextView
android:id="@+id/break_time"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:gravity="center_vertical"
android:textSize="18sp"
tools:text="1 h 30 m" />
</LinearLayout>
style="@style/container_subtext"
tools:text="Hourly - $23/Hour" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:id="@+id/container_four"
style="@style/container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/units_holder">
android:elevation="3dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/container_two"
app:layout_constraintWidth_percent="0.5">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:alpha="0.45"
style="@style/container_icon"
android:src="@drawable/break_time" />
<TextView
android:id="@+id/break_time"
style="@style/container_subtext"
tools:text="1 h 30 m" />
</LinearLayout>
<LinearLayout
android:id="@+id/container_five"
style="@style/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/container_three">
<ImageView
style="@style/container_icon"
android:src="@drawable/box_icon" />
<TextView
android:id="@+id/units"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:gravity="center_vertical"
android:textSize="18sp"
style="@style/container_subtext"
tools:text="6 h 30 m" />
</LinearLayout>
<LinearLayout
android:id="@+id/container_six"
style="@style/container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/container_five">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:alpha="0.45"
style="@style/container_icon"
android:src="@drawable/marker" />
<TextView
android:id="@+id/location"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:gravity="center_vertical"
android:textSize="18sp"
style="@style/container_subtext"
tools:text="Bundaberg" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:background="@color/colorInvalid"
android:layout_width="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_height="1dp"/>
<TextView
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:id="@+id/title"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
android:gravity="center_vertical"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
tools:text="Title"/>
</LinearLayout>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/nav_settings"
android:icon="@drawable/ic_settings_white_24dp"
app:showAsAction="always"
android:title="@string/title_settings" />
</menu>

View File

@@ -4,11 +4,12 @@
<item
android:id="@+id/app_bar_filter"
android:icon="@drawable/ic_filter_list_black_24dp"
android:icon="@android:drawable/ic_menu_search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
android:title="Filter"
android:focusable="true"
android:focusableInTouchMode="true"
app:showAsAction="always"/>
app:showAsAction="always" />
<item
android:id="@+id/app_bar_soft"

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/nav_add_shift"
android:icon="@android:drawable/ic_menu_edit"
android:title="Edit"
app:showAsAction="always" />
</menu>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/add_shift_navigation"
app:startDestination="@id/addShiftFragment">
<fragment
android:id="@+id/addShiftFragment"
android:name="com.appttude.h_mal.days_left.ui.addShift.AddShiftFragment"
android:label="Add Shift"
tools:layout="@layout/fragment_add_shift">
<action
android:id="@+id/addShift_to_employersFragment_2"
app:destination="@id/employersFragment" />
<action
android:id="@+id/addShift_to_tasksFragment"
app:destination="@id/tasksFragment" />
</fragment>
<fragment
android:id="@+id/employersFragment"
android:name="com.appttude.h_mal.days_left.ui.addShift.EmployersFragment"
android:label="fragment_employers"
tools:layout="@layout/fragment_employers" >
<action
android:id="@+id/employers_to_addEmployerFragment"
app:destination="@id/addEmployerFragment"
app:popUpTo="@id/addShiftFragment"/>
</fragment>
<fragment
android:id="@+id/addEmployerFragment"
android:name="com.appttude.h_mal.days_left.ui.addShift.AddEmployerFragment"
android:label="AddEmployerFragment" />
<fragment
android:id="@+id/addTaskFragment"
android:name="com.appttude.h_mal.days_left.ui.addShift.AddTaskFragment"
android:label="AddTaskFragment" />
<fragment
android:id="@+id/tasksFragment"
android:name="com.appttude.h_mal.days_left.ui.addShift.TasksFragment"
android:label="fragment_tasks"
tools:layout="@layout/fragment_tasks" >
<action
android:id="@+id/action_tasksFragment_to_addTaskFragment"
app:destination="@id/addTaskFragment" />
</fragment>
</navigation>

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