- 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> <PersistentState>
<option name="values"> <option name="values">
<map> <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> </map>
</option> </option>
</PersistentState> </PersistentState>
@@ -33,8 +33,7 @@
</option> </option>
<option name="values"> <option name="values">
<map> <map>
<entry key="color" value="ffffff" /> <entry key="outputName" value="ic_baseline_attach_money_24" />
<entry key="outputName" value="ic_filter_list_black_24dp" />
<entry key="sourceFile" value="C:\Users\h_mal" /> <entry key="sourceFile" value="C:\Users\h_mal" />
</map> </map>
</option> </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"> <component name="navEditor-manualLayoutAlgorithm2">
<option name="myPositions"> <option name="myPositions">
<map> <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"> <entry key="auth_navigation.xml">
<value> <value>
<LayoutPositions> <LayoutPositions>
@@ -173,6 +275,226 @@
</LayoutPositions> </LayoutPositions>
</value> </value>
</entry> </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> </map>
</option> </option>
</component> </component>

View File

@@ -8,6 +8,10 @@ apply plugin: 'com.google.gms.google-services'
// Android navigation // Android navigation
apply plugin: 'androidx.navigation.safeargs' apply plugin: 'androidx.navigation.safeargs'
apply plugin: 'com.google.firebase.crashlytics'
repositories {
mavenCentral()
}
android { android {
compileSdkVersion 29 compileSdkVersion 29
@@ -55,24 +59,39 @@ dependencies {
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.exifinterface:exifinterface:1.2.0' implementation 'androidx.exifinterface:exifinterface:1.2.0'
implementation 'com.google.android.material:material:1.1.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 // Testing
testImplementation 'junit:junit:4.13' testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 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 // Gson
implementation 'com.google.code.gson:gson:2.3.1' implementation 'com.google.code.gson:gson:2.8.5'
// Google Play Services // 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 // Firebase
implementation 'com.google.firebase:firebase-core:16.0.1' implementation 'com.google.firebase:firebase-core:17.4.4'
implementation 'com.google.firebase:firebase-auth:16.2.1' implementation 'com.google.firebase:firebase-auth:19.3.2'
implementation 'com.google.firebase:firebase-storage:16.0.1' implementation 'com.google.firebase:firebase-storage:19.1.1'
implementation 'com.google.firebase:firebase-database:16.0.1' implementation 'com.google.firebase:firebase-database:19.3.1'
implementation 'com.firebaseui:firebase-ui-database:1.1.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 //Picasso - load images
implementation 'com.squareup.picasso:picasso:2.71828' implementation 'com.squareup.picasso:picasso:2.71828'
// Zoomable Image view // Zoomable Image view
@@ -85,8 +104,3 @@ dependencies {
implementation "com.github.SUPERCILEX.poi-android:poi:3.17" 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; package com.appttude.h_mal.days_left;
import android.content.Context; import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; 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. * Instrumented test, which will execute on an Android device.

View File

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

View File

@@ -5,70 +5,76 @@ import android.view.View
import com.appttude.h_mal.days_left.models.ShiftObject import com.appttude.h_mal.days_left.models.ShiftObject
import com.firebase.ui.database.FirebaseListAdapter import com.firebase.ui.database.FirebaseListAdapter
import com.google.firebase.database.Query 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) { FirebaseListAdapter<ShiftObject>(activity, modelClass, modelLayout, ref) {
override fun populateView(v: View?, model: ShiftObject?, position: Int) { override fun populateView(v: View?, model: ShiftObject?, position: Int) {
v?.farm_name?.text = model?.abnObject?.abn // v?.farm_name?.text = model?.abnObject?.abn
v?.date?.text = model?.shiftDate // v?.date?.text = model?.shiftDate
v?.task_name?.text = model?.taskObject?.task // v?.task_name?.text = model?.taskObject?.task
v?.type?.text = model?.taskObject?.workType // v?.type?.text = model?.taskObject?.workType
val locationString:String = model?.abnObject?.state + " - " + model?.abnObject?.postCode // val locationString:String = model?.abnObject?.state + " - " + model?.abnObject?.postCode
v?.location?.text = locationString // v?.location?.text = locationString
//
v?.farm_name?.text = model?.abnObject?.companyName // v?.farm_name?.text = model?.abnObject?.companyName
//
var s = model?.taskObject?.workType + " - $" + model?.taskObject?.rate + "/" // var s = model?.taskObject?.workType + " - $" + model?.taskObject?.rate + "/"
//
if (model?.taskObject?.workType == FirebaseClass.HOURLY){ // if (model?.taskObject?.workType == FirebaseClass.HOURLY){
s = "$s Hour" // s = "$s Hour"
v?.time_holder?.visibility = View.VISIBLE // v?.container_three?.visibility = View.VISIBLE
v?.units_holder?.visibility = View.GONE // v?.container_five?.visibility = View.GONE
//
val time = model.timeObject?.timeIn + " - " + model.timeObject!!.timeOut // val time = model.timeObject?.timeIn + " - " + model.timeObject!!.timeOut
v?.time?.text = time // v?.time?.text = time
//
model.timeObject!!.breakEpoch.let { mins -> // model.timeObject!!.breakEpoch.let { mins ->
val breakHolder = v?.break_holder // val breakHolder = v?.container_four
if (mins > 0){ // if (mins > 0){
breakHolder?.visibility = View.VISIBLE // breakHolder?.visibility = View.VISIBLE
v?.break_time?.text = getBreakTimeString(model.timeObject!!.breakEpoch) // v?.break_time?.text = getBreakTimeString(model.timeObject!!.breakEpoch)
}else{ // }else{
breakHolder?.visibility = View.GONE // breakHolder?.visibility = View.GONE
} // }
} // }
}else{ // }else{
s = "$s Unit" // s = "$s Unit"
v?.time_holder?.visibility = View.GONE // v?.container_three?.visibility = View.GONE
v?.units_holder?.visibility = View.VISIBLE // v?.container_five?.visibility = View.VISIBLE
//
v?.units?.text = model?.unitsCount.toString() // v?.units?.text = model?.unitsCount.toString()
} // }
//
v?.type?.text = s // 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 = "" // private fun getBreakTimeString(breakMins: Int): String {
if (hoursInt > 0) { // val hoursFloat = (breakMins / 60).toFloat()
s = "$hoursInt h " //
} // 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 package com.appttude.h_mal.days_left.application
import android.app.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.FirebaseAuthSource
import com.appttude.h_mal.days_left.data.firebase.FirebaseDataSource 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.data.firebase.FirebaseFunctionsSource
import com.appttude.h_mal.days_left.ui.main.MainViewModelFactory 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.appttude.h_mal.days_left.ui.main.ShiftsViewModelFactory
import com.google.gson.Gson
import org.kodein.di.Kodein import org.kodein.di.Kodein
import org.kodein.di.KodeinAware import org.kodein.di.KodeinAware
import org.kodein.di.android.x.androidXModule import org.kodein.di.android.x.androidXModule
@@ -15,24 +18,30 @@ import org.kodein.di.generic.instance
import org.kodein.di.generic.provider import org.kodein.di.generic.provider
import org.kodein.di.generic.singleton import org.kodein.di.generic.singleton
class AppClass : Application(), KodeinAware{ class AppClass : Application(), KodeinAware {
override val kodein = Kodein.lazy { override val kodein = Kodein.lazy {
import(androidXModule(this@AppClass)) import(androidXModule(this@AppClass))
bind() from singleton { Gson() }
bind() from singleton { PreferenceSource(instance()) }
bind() from singleton { FirebaseAuthSource() } bind() from singleton { FirebaseAuthSource() }
bind() from singleton { FirebaseDataSource() } bind() from singleton { FirebaseDataSource() }
bind() from singleton { FirebaseFunctionsSource() }
bind() from singleton { bind() from singleton {
UserRepository( FirebaseRepository(
instance(),
instance(),
instance() instance()
) )
} }
bind() from provider { MainViewModelFactory( instance() ) } bind() from singleton { ShiftHelper() }
// bind() from provider { MainViewModelFactory( instance() ) }
bind() from provider { bind() from provider {
ShiftsViewModelFactory( instance() ) ShiftsViewModelFactory(instance(), instance())
} }
bind() from provider { bind() from provider {
AuthViewModelFactory( instance() ) AuthViewModelFactory(instance())
} }
} }
} }

View File

@@ -1,35 +1,35 @@
package com.appttude.h_mal.days_left.data.firebase package com.appttude.h_mal.days_left.data.firebase
import com.appttude.h_mal.days_left.FirebaseClass import com.appttude.h_mal.days_left.utils.*
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.google.firebase.database.FirebaseDatabase 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{ class FirebaseDataSource{
private val firebaseDatabase: FirebaseDatabase by lazy { private val firebaseDatabase: FirebaseDatabase by lazy {
FirebaseDatabase.getInstance() FirebaseDatabase.getInstance()
} }
private val mDatabase = firebaseDatabase.reference 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 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( fun shiftsRef(uid: String) = usersRef.child(uid).child(SHIFT_FIREBASE)
FirebaseClass.TASK_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 package com.appttude.h_mal.days_left.data.firebase
import com.google.android.gms.tasks.Task import com.google.android.gms.tasks.Task
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.functions.FirebaseFunctions import com.google.firebase.functions.FirebaseFunctions
import com.google.firebase.functions.HttpsCallableResult import com.google.firebase.functions.HttpsCallableResult
import java.util.HashMap import java.util.*
class FirebaseFunctionsSource { 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.DatabaseError
import com.google.firebase.database.Query import com.google.firebase.database.Query
import com.google.firebase.database.ValueEventListener import com.google.firebase.database.ValueEventListener
import com.google.gson.reflect.TypeToken
class FirebaseQueryLiveData( class FirebaseQueryLiveData(
@@ -30,3 +31,112 @@ 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.ViewModel
import androidx.lifecycle.ViewModelProvider 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. * ViewModel provider factory to instantiate LoginViewModel.
* Required given LoginViewModel has a non-empty constructor * Required given LoginViewModel has a non-empty constructor
*/ */
class AuthViewModelFactory( class AuthViewModelFactory(
private val userRepository: UserRepository private val firebaseRepository: FirebaseRepository
) : ViewModelProvider.Factory { ) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@@ -17,7 +17,7 @@ class AuthViewModelFactory(
if (modelClass.isAssignableFrom(AuthViewModel::class.java)) { if (modelClass.isAssignableFrom(AuthViewModel::class.java)) {
return ( return (
AuthViewModel( AuthViewModel(
userRepository firebaseRepository
) )
) as T ) as T
} }

View File

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

View File

@@ -1,13 +1,10 @@
package com.appttude.h_mal.days_left.ui.login package com.appttude.h_mal.days_left.ui.login
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.fragment.app.FragmentManager import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.appttude.h_mal.days_left.R 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.hide
import com.appttude.h_mal.days_left.utils.show import com.appttude.h_mal.days_left.utils.show
import com.appttude.h_mal.days_left.utils.showToast 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 -> it.getContentIfNotHandled()?.let { message ->
showToast(message) showToast(message)
} }

View File

@@ -6,7 +6,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.appttude.h_mal.days_left.R 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.afterTextChanged
@@ -14,13 +14,12 @@ import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_login.* import kotlinx.android.synthetic.main.fragment_login.*
import org.kodein.di.KodeinAware import org.kodein.di.KodeinAware
import org.kodein.di.android.x.kodein import org.kodein.di.android.x.kodein
import org.kodein.di.generic.instance
class LoginFragment : Fragment(), KodeinAware { class LoginFragment : Fragment(), KodeinAware {
override val kodein by kodein() 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( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, 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 { viewModel.loginFormState.observe(viewLifecycleOwner, Observer {
val loginState = it ?: return@Observer val loginState = it ?: return@Observer

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,200 +1,82 @@
package com.appttude.h_mal.days_left.ui.main package com.appttude.h_mal.days_left.ui.main
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.Menu
import androidx.appcompat.app.ActionBarDrawerToggle import android.view.MenuItem
import androidx.activity.viewModels import androidx.activity.viewModels
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.fragment.app.FragmentManager
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat import androidx.lifecycle.Observer
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.appttude.h_mal.days_left.* import androidx.navigation.NavController
import com.appttude.h_mal.days_left.ui.login.FullscreenActivity import androidx.navigation.fragment.NavHostFragment
import com.appttude.h_mal.days_left.FirebaseClass.Companion.SHIFT_FIREBASE import androidx.navigation.ui.AppBarConfiguration
import com.appttude.h_mal.days_left.FirebaseClass.Companion.USER_FIREBASE import androidx.navigation.ui.NavigationUI
import com.appttude.h_mal.days_left.FirebaseClass.Companion.auth import androidx.navigation.ui.setupActionBarWithNavController
import com.appttude.h_mal.days_left.FirebaseClass.Companion.mDatabase import androidx.navigation.ui.setupWithNavController
import com.appttude.h_mal.days_left.models.ShiftObject import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.main.home.HomeFragment import com.appttude.h_mal.days_left.ui.login.AuthViewModel
import com.appttude.h_mal.days_left.ui.main.list.FragmentList import com.appttude.h_mal.days_left.ui.login.AuthViewModelFactory
import com.appttude.h_mal.days_left.ui.main.tools.FragmentTools import com.appttude.h_mal.days_left.utils.setVis
import com.google.android.material.navigation.NavigationView
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_drawer_main.*
import kotlinx.android.synthetic.main.activity_main.* 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.KodeinAware
import org.kodein.di.android.kodein import org.kodein.di.android.kodein
import org.kodein.di.android.x.kodein
import org.kodein.di.generic.instance import org.kodein.di.generic.instance
class MainActivity : AppCompatActivity(), KodeinAware { class MainActivity : AppCompatActivity(), KodeinAware {
override val kodein by kodein() override val kodein by kodein()
private val factory by instance<MainViewModelFactory>() private val factory by instance<AuthViewModelFactory>()
private val factory2 by instance<ShiftsViewModelFactory>() private val factory2 by instance<ShiftsViewModelFactory>()
val viewModel: MainViewModel by viewModels{ factory } val viewModel: AuthViewModel by viewModels{ factory }
companion object{ private lateinit var navController : NavController
var shiftList = ArrayList<ShiftObject>()
val ref = mDatabase.child(USER_FIREBASE).child(auth.uid as String).child(SHIFT_FIREBASE)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_drawer_main) setContentView(R.layout.activity_main)
ViewModelProvider(this, factory2).get(ShiftsViewModel::class.java) ViewModelProvider(this, factory2).get(ShiftsViewModel::class.java)
//setup backstack change listener
supportFragmentManager.addOnBackStackChangedListener(backStackChangedListener)
//set toolbar //set toolbar
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
//setup fab // initiate nav host for android navigation
fab.setOnClickListener{ val navHost = supportFragmentManager
val intent = Intent(this, AddShiftActivity::class.java) .findFragmentById(R.id.container) as NavHostFragment
startActivity(intent) // instantiate controller for nav host
} navController = navHost.navController
// setup bottom bar with tabs
//setup drawer layout setupBottomBar()
val toggle = ActionBarDrawerToggle(this,drawer_layout,toolbar,R.string.navigation_drawer_open, R.string.navigation_drawer_close) // progress view for async operations
drawer_layout.addDrawerListener(toggle) viewModel.operationState.observe(this, Observer {
toggle.syncState() progressBar2.setVis(it)
})
//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
} }
private val onNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> private fun setupBottomBar(){
when (item.itemId) { val tabs = setOf(R.id.navigation_home, R.id.navigation_list, R.id.navigation_tools)
R.id.navigation_home -> { val appBarConfiguration = AppBarConfiguration(tabs)
supportFragmentManager.beginTransaction().replace(R.id.container,
HomeFragment() setupActionBarWithNavController(navController, appBarConfiguration)
).commit() navigation.setupWithNavController(navController)
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 val backStackChangedListener = FragmentManager.OnBackStackChangedListener { override fun onCreateOptionsMenu(menu: Menu?): Boolean {
supportFragmentManager.fragments[0].javaClass.simpleName.let { fragmentName -> menuInflater.inflate(R.menu.menu, menu)
return true
}
when (fragmentName){ override fun onOptionsItemSelected(item: MenuItem): Boolean {
"HomeFragment" -> { return when (item.itemId) {
title = "Home" android.R.id.home -> {
} onBackPressed()
"ListFragment" -> { true
title = "List" }
} R.id.nav_settings ->{
"ToolsFragment" -> { NavigationUI.onNavDestinationSelected(item, navController)
title = "Tools" true
} }
else -> { else -> {
title = getString(R.string.app_name) 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.ViewModel
import androidx.lifecycle.ViewModelProvider 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. * ViewModel provider factory to instantiate LoginViewModel.
* Required given LoginViewModel has a non-empty constructor * Required given LoginViewModel has a non-empty constructor
*/ */
class MainViewModelFactory( class MainViewModelFactory(
private val userRepository: UserRepository private val firebaseRepository: FirebaseRepository
) : ViewModelProvider.Factory { ) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@@ -17,7 +17,7 @@ class MainViewModelFactory(
if (modelClass.isAssignableFrom(MainViewModel::class.java)) { if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return ( return (
MainViewModel( MainViewModel(
userRepository firebaseRepository
) )
) as T ) as T
} }

View File

@@ -1,88 +1,204 @@
package com.appttude.h_mal.days_left.ui.main package com.appttude.h_mal.days_left.ui.main
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.appttude.h_mal.days_left.data.firebase.FirebaseDataSource import com.appttude.h_mal.days_left.data.repository.FirebaseRepository
import com.appttude.h_mal.days_left.firebaseUtils.FirebaseQueryLiveData 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.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 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( class ShiftsViewModel(
val database: FirebaseDataSource val repository: FirebaseRepository,
): ViewModel() { val gson: Gson
) : ViewModel() {
val shifts = database.allShifts() // Live date of operation success
val shiftData = FirebaseQueryLiveData(shifts) 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 liveData = MutableLiveData<Triple<List<ShiftObject?>, Int, IntArray>>()
val currentShift = MutableLiveData<ShiftObject>()
init { init {
shiftData.observeForever { shiftData.observeForever {
val list = it.mapSnapToShiftList() val shifts = it.map { item -> item.second }
val uniqueEntries = countDistinct(list) val uniqueEntries = countDistinct(shifts)
val shiftTypeCount = countShiftType(list) val shiftTypeCount = countShiftType(shifts)
liveData.value = Triple( liveData.value = Triple(
list, shifts,
uniqueEntries, uniqueEntries,
shiftTypeCount 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 { 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 { 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 val j = list.size - i
return intArrayOf(i, j) 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.ViewModel
import androidx.lifecycle.ViewModelProvider 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. * ViewModel provider factory to instantiate LoginViewModel.
* Required given LoginViewModel has a non-empty constructor * Required given LoginViewModel has a non-empty constructor
*/ */
class ShiftsViewModelFactory( class ShiftsViewModelFactory(
private val firebaseDatabase: FirebaseDataSource private val firebaseDatabase: FirebaseRepository,
private val gson: Gson
) : ViewModelProvider.Factory { ) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@@ -17,7 +19,8 @@ class ShiftsViewModelFactory(
if (modelClass.isAssignableFrom(ShiftsViewModel::class.java)) { if (modelClass.isAssignableFrom(ShiftsViewModel::class.java)) {
return ( return (
ShiftsViewModel( ShiftsViewModel(
firebaseDatabase firebaseDatabase,
gson
) )
) as T ) 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 package com.appttude.h_mal.days_left.ui.main.list
import android.app.AlertDialog import android.app.AlertDialog
import android.content.DialogInterface
import android.content.DialogInterface.BUTTON_POSITIVE
import android.content.Intent import android.content.Intent
import android.database.DataSetObserver
import android.os.Bundle import android.os.Bundle
import android.view.* import android.view.*
import android.widget.AdapterView import androidx.appcompat.widget.SearchView
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.appttude.h_mal.days_left.* import androidx.navigation.fragment.findNavController
import com.appttude.h_mal.days_left.CustomDialog.Companion.dateSelectionFrom import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.CustomDialog.Companion.dateSelectionTo import com.appttude.h_mal.days_left.ui.addShift.AddNewShiftActivity
import com.appttude.h_mal.days_left.FirebaseClass.Companion.SHIFT_ID import com.appttude.h_mal.days_left.ui.addShift.AddShiftActivity
import com.appttude.h_mal.days_left.models.AbnObject import com.appttude.h_mal.days_left.ui.addShift.AddShiftFragment
import com.appttude.h_mal.days_left.models.ShiftObject import com.appttude.h_mal.days_left.ui.login.FullscreenActivity
import com.appttude.h_mal.days_left.ui.main.MainActivity
import com.appttude.h_mal.days_left.ui.main.MainActivity.Companion.ref
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModel import com.appttude.h_mal.days_left.ui.main.ShiftsViewModel
import com.firebase.ui.database.FirebaseRecyclerAdapter import com.appttude.h_mal.days_left.ui.main.list.ShiftListRecyclerAdapter.Sortation
import com.google.firebase.FirebaseOptions import com.appttude.h_mal.days_left.ui.splashScreen.SplashFragment
import com.google.firebase.database.Query import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.dialog_previous_abns_used.view.* import com.appttude.h_mal.days_left.utils.showToast
import kotlinx.android.synthetic.main.fragment_list.* 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() val viewModel: ShiftsViewModel by activityViewModels()
lateinit var fireAdapter: FireAdapter lateinit var fireAdapter: ShiftListRecyclerAdapter
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
@@ -43,37 +36,30 @@ class FragmentList : androidx.fragment.app.Fragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
//set custom firebase adapter on listview //set custom firebase adapter on listview
add_test.setOnClickListener {
view.navigateTo(R.id.list_to_addShiftActivity)
}
fireAdapter = FireAdapter( fireAdapter =
activity, ShiftListRecyclerAdapter(
ShiftObject::class.java, view,
R.layout.list_item, viewModel
viewModel.shifts )
)
page_two_list.apply { recycler_view.apply {
adapter = fireAdapter adapter = fireAdapter
// onItemLongClickListener =
onItemClickListener = // AdapterView.OnItemLongClickListener { _, _, position, _ ->
AdapterView.OnItemClickListener { _, _, position, _ -> // AlertDialog.Builder(context).apply {
val refId = fireAdapter.getId(position) // setTitle("Are you sure you want to delete?")
val intent = Intent(activity, AddShiftActivity::class.java) // setNegativeButton(android.R.string.no, null)
intent.putExtra(SHIFT_ID, refId) // setPositiveButton(android.R.string.yes) { _, _ ->
startActivity(intent) // fireAdapter.getRef(position).removeValue()
} // }
// create().show()
onItemLongClickListener = // }
AdapterView.OnItemLongClickListener { _, _, position, _ -> // true
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) setHasOptionsMenu(true)
} }
@@ -81,14 +67,14 @@ class FragmentList : androidx.fragment.app.Fragment() {
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater) super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.menu_list_fragment, menu) 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 { override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.app_bar_filter -> {
filterData()
return false
}
R.id.app_bar_soft -> { R.id.app_bar_soft -> {
sortData() sortData()
return false return false
@@ -106,31 +92,15 @@ class FragmentList : androidx.fragment.app.Fragment() {
setSingleChoiceItems(groupName, checkedItem) { dialog, item -> setSingleChoiceItems(groupName, checkedItem) { dialog, item ->
when (item) { when (item) {
0 -> { 0 -> {
val q1 = fireAdapter.filterShifts(Sortation.Name())
}
viewModel.shifts.orderByChild("abnObject/companyName").equalTo("GREEN CLOUD NURSERY") 1 -> {
fireAdapter.notifyDataSetChanged() fireAdapter.filterShifts(Sortation.DateAdded())
// fireAdapter = FireAdapter( }
// activity, 2 ->{
// ShiftObject::class.java, fireAdapter.filterShifts(Sortation.ShiftDate())
// R.layout.list_item,
// q1
// )
} }
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() dialog.dismiss()
} }
create().show() create().show()
@@ -138,116 +108,130 @@ class FragmentList : androidx.fragment.app.Fragment() {
} }
private fun filterData() { override fun onQueryTextSubmit(query: String?): Boolean {
val groupName = arrayOf("Name", "Date Added", "Shift Type")
val checkedItem = -1
val builder = AlertDialog.Builder(context) return true
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()
}
}
})
} }
fun turnToUniqueAbnObject(shifts: ArrayList<ShiftObject>): List<AbnObject> { override fun onQueryTextChange(newText: String?): Boolean {
val abnList = mutableListOf<AbnObject>() if (newText.isNullOrBlank()){
fireAdapter.filterList(null)
shifts.forEach { shiftObject -> }else{
shiftObject.abnObject?.let { abnList.add(it) } fireAdapter.filterList(newText)
} }
return false
return abnList.distinct()
} }
fun applyFilter(arg1: String, arg2: String?) { // private fun filterData() {
val q1: Query // val groupName = arrayOf("Name", "Date Added", "Shift Type")
if (arg2 == null) { // val checkedItem = -1
q1 = ref.orderByChild("abnObject/abn").equalTo(arg1) //
} else { // val builder = AlertDialog.Builder(context)
q1 = ref.orderByChild("shiftDate").startAt(arg1).endAt(arg2) // builder.setTitle("Filter by:")
} // builder.setSingleChoiceItems(
// groupName,
fireAdapter = FireAdapter( // checkedItem,
activity, // DialogInterface.OnClickListener { dialog, item ->
ShiftObject::class.java, // dialog.dismiss()
R.layout.list_item, //
q1 // when (item) {
) // 0 -> {
page_two_list.adapter = fireAdapter // 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.Bundle
import android.os.Environment import android.os.Environment
import android.util.Log import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.core.content.ContextCompat.checkSelfPermission import androidx.core.content.ContextCompat.checkSelfPermission
import androidx.core.content.FileProvider 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.BuildConfig
import com.appttude.h_mal.days_left.R 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.OnCompleteListener
import com.google.android.gms.tasks.Task import com.google.android.gms.tasks.Task
import com.google.firebase.functions.FirebaseFunctions import com.google.firebase.functions.FirebaseFunctions
import com.google.firebase.functions.FirebaseFunctionsException
import com.google.firebase.storage.FirebaseStorage import com.google.firebase.storage.FirebaseStorage
import kotlinx.android.synthetic.main.fragment_tools.* import kotlinx.android.synthetic.main.fragment_tools.*
import java.io.File import java.io.File
import java.util.HashMap import java.util.*
class FragmentTools : Fragment() { class FragmentTools : Fragment() {
@@ -43,15 +45,14 @@ class FragmentTools : Fragment() {
return inflater.inflate(R.layout.fragment_tools, container, false) return inflater.inflate(R.layout.fragment_tools, container, false)
} }
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState) super.onViewCreated(view, savedInstanceState)
compile.setOnClickListener(onClickListener) compile.setOnClickListener(onClickListener)
summary_button.setOnClickListener(onClickListener) summary_button.setOnClickListener(onClickListener)
} }
internal val onClickListener = View.OnClickListener { view -> private val onClickListener = View.OnClickListener { view ->
requestPermissions().let { requestPermissions().let {
if (it) { if (it) {
if (view.id == R.id.compile){ if (view.id == R.id.compile){
@@ -64,44 +65,33 @@ class FragmentTools : Fragment() {
} }
internal val complete = OnCompleteListener<String>{task -> private val complete = OnCompleteListener<String>{ task ->
if (!task.isSuccessful) { task.safeFirebaseResult({
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 savePath = Environment.getExternalStorageDirectory().toString() + "/DaysLeftTemp"
val file = File(savePath) val file = File(savePath)
if (!file.exists()) { if (!file.exists()) {
file.mkdirs() file.mkdirs()
} }
it ?: return@safeFirebaseResult
val fbstore = storage.reference.child(it)
val strings = it.split("/").toTypedArray()
val myFile = File(savePath, strings.last()) val myFile = File(savePath, strings.last())
fbstore.getFile(myFile).addOnSuccessListener { fbstore.getFile(myFile).safeFirebaseResult({
// Local temp file has been created // Local temp file has been created
val data = val data =
FileProvider.getUriForFile(context!!, BuildConfig.APPLICATION_ID + ".provider", myFile) FileProvider.getUriForFile(
requireContext(),
BuildConfig.APPLICATION_ID + ".provider",
myFile
)
activity?.grantUriPermission( activity?.grantUriPermission(
activity?.getPackageName(), activity?.packageName,
data, data,
Intent.FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION
) )
val intent1 = Intent(Intent.ACTION_VIEW) val intent1 = Intent(Intent.ACTION_VIEW)
.setDataAndType(data, "application/vnd.ms-excel") .setDataAndType(data, "application/vnd.ms-excel")
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
@@ -109,16 +99,72 @@ class FragmentTools : Fragment() {
try { try {
activity?.startActivity(intent1) activity?.startActivity(intent1)
} catch (e: ActivityNotFoundException) { } catch (e: ActivityNotFoundException) {
Toast.makeText(activity, "No Application Available to View Excel", Toast.LENGTH_SHORT) context?.showToast("No Application Available to View Excel")
.show()
} }
},{
},{
}.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> { fun writeToExcel(): Task<String> {
@@ -164,7 +210,7 @@ class FragmentTools : Fragment() {
} }
fun requestPermissions() : Boolean{ fun requestPermissions() : Boolean{
if (checkSelfPermission(context!!, Manifest.permission.WRITE_EXTERNAL_STORAGE) if (checkSelfPermission(requireContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(context,"not granted",Toast.LENGTH_SHORT).show() 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 package com.appttude.h_mal.days_left.utils
import android.text.TextUtils
import java.util.regex.Pattern import java.util.regex.Pattern
// Password must contain 8-16 characters, // Password must contain 8-16 characters,
@@ -13,9 +12,12 @@ fun isPasswordValid(password: String?): Boolean {
} }
fun isNameValid(name: String?): Boolean { fun isNameValid(name: String?): Boolean {
return name?.let { return !name.isNullOrBlank()
Pattern.compile("[a-zA-Z]{4,}(?: [a-zA-Z]+){0,2}\$").matcher(it).find()
} ?: false // 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 { 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.app.Activity
import android.content.Context import android.content.Context
import android.net.Uri
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.EditText import android.widget.EditText
import android.widget.ImageView
import android.widget.Toast import android.widget.Toast
import androidx.annotation.StringRes 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.NavDirections
import androidx.navigation.Navigation import androidx.navigation.Navigation
import com.squareup.picasso.Picasso import androidx.navigation.findNavController
import java.lang.Exception import com.appttude.h_mal.days_left.R
import com.google.android.material.textfield.TextInputLayout
fun View.show() { fun View.show() {
this.visibility = View.VISIBLE visibility = View.VISIBLE
} }
fun View.hide() { 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) { fun Context.showToast(message: String) {
@@ -32,36 +45,72 @@ fun Context.showToast(@StringRes resourceId: Int) {
Toast.makeText(this, resourceId, Toast.LENGTH_LONG).show() Toast.makeText(this, resourceId, Toast.LENGTH_LONG).show()
} }
fun Context.hideKeyboard(view: View?) { fun View.hideKeyboard() {
val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager val inputMethodManager =
inputMethodManager.hideSoftInputFromWindow(view?.windowToken, 0) context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
} }
fun View.navigateTo(navigationId: Int) { fun View.navigateTo(navigationId: Int) {
try { findNavController().navigate(navigationId)
Navigation.findNavController(this).navigate(navigationId)
}catch (e: IllegalArgumentException){
e.printStackTrace()
}
} }
fun View.navigateTo(navDirections: NavDirections) { fun View.navigateTo(navDirections: NavDirections) {
Navigation.findNavController(this).navigate(navDirections) Navigation.findNavController(this).navigate(navDirections)
} }
fun View.popBack(){
Navigation.findNavController(this).popBackStack()
}
fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) { fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
this.addTextChangedListener(object : TextWatcher { this.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(editable: Editable?) { override fun afterTextChanged(editable: Editable?) {
afterTextChanged.invoke(editable.toString()) afterTextChanged.invoke(editable.toString())
} }
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: 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?) { //fun ImageView.setPicassoIcon(profileUrl: String?) {
// val width = layoutParams?.width?.takeIf { it > 0 } // val width = layoutParams?.width?.takeIf { it > 0 }
// val height = layoutParams?.height?.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 import com.google.gson.reflect.TypeToken
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type 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"?> <?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:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" tools:context=".ui.addShift.AddShiftActivity">
android:paddingLeft="@dimen/activity_horizontal_margin" <com.google.android.material.appbar.AppBarLayout
android:paddingTop="@dimen/activity_vertical_margin" android:layout_alignParentTop="true"
android:paddingRight="@dimen/activity_horizontal_margin" android:id="@+id/appbar"
android:paddingBottom="@dimen/activity_vertical_margin" android:layout_width="match_parent"
tools:context=".AddItems.AddEmployerFragment"> 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 <ProgressBar
android:id="@+id/progressBar2"
style="?android:attr/progressBarStyle"
android:visibility="gone"
android:layout_centerInParent="true"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/progress_bar" app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone"/> app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout </androidx.constraintlayout.widget.ConstraintLayout>
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,11 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <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" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical">
tools:context=".Login.ChangeUserDetailsActivity">
<LinearLayout <LinearLayout
android:id="@+id/ph_view_holder" android:id="@+id/ph_view_holder"

View File

@@ -32,26 +32,19 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<FrameLayout <fragment
android:layout_below="@id/appbar" android:layout_below="@id/appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_above="@id/navigation" 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_constraintBottom_toTopOf="@id/navigation"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/appbar" app:layout_constraintTop_toBottomOf="@id/appbar"
android:id="@+id/container"> 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>
<ProgressBar <ProgressBar
android:id="@+id/progressBar2" android:id="@+id/progressBar2"
@@ -66,13 +59,12 @@
<com.google.android.material.bottomnavigation.BottomNavigationView <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/navigation" android:id="@+id/navigation"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="?android:attr/windowBackground" android:background="?android:attr/windowBackground"
app:menu="@menu/navigation"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/> app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/navigation"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <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_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">

View File

@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <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_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
@@ -20,12 +18,6 @@
android:gravity="center" android:gravity="center"
android:text="Start" /> android:text="Start" />
<!--<ImageView-->
<!--android:layout_width="1dp"-->
<!--android:background="#8aa4bf"-->
<!--android:layout_height="match_parent"-->
<!--android:layout_margin="4dp"/>-->
<TextView <TextView
android:id="@+id/to_date" android:id="@+id/to_date"
android:layout_width="0dp" android:layout_width="0dp"
@@ -45,47 +37,27 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:headerBackground="@color/colorPrimaryDark" 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_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="right|bottom"> android:text="Break (in minutes) : " />
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/breaktime"
android:layout_height="wrap_content" android:layout_width="60dp"
android:text="Break (in minutes) : " /> android:layout_height="wrap_content"
android:inputType="number"
<EditText android:text="0"/>
android:id="@+id/breaktime" </LinearLayout>
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" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <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" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical">
tools:context=".AddItems.AddEmployerFragment">
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout" 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_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin" tools:context=".ui.addShift.AddEmployerFragment">
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin" <androidx.recyclerview.widget.RecyclerView
android:paddingBottom="@dimen/activity_vertical_margin" android:id="@+id/searched_abn_recycler"
tools:context=".AddItemActivity"> 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 <ProgressBar
android:id="@+id/spinning_pb" android:id="@+id/searched_abn_progbar"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="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"/>
</androidx.constraintlayout.widget.ConstraintLayout> </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"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin" 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"?> <?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" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.appttude.h_mal.days_left.ui.main.list.FragmentList"> tools:context="com.appttude.h_mal.days_left.ui.main.list.FragmentList">
<ListView <LinearLayout
android:id="@+id/page_two_list" android:id="@+id/top_container"
android:layout_width="match_parent" 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_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
android:text="Enter Your Password" /> android:text="Enter Your Password Again" />
<TextView <TextView
android:id="@+id/submission_subtitle_tv" 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"?> <?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_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools" 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 <androidx.cardview.widget.CardView
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintWidth_percent="0.5"
android:layout_marginLeft="12dp" android:layout_marginLeft="12dp"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:layout_marginRight="12dp" android:layout_marginRight="12dp"
android:layout_marginBottom="6dp" 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"> app:cardCornerRadius="@dimen/card_radius">
<FrameLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_margin="16dp"> android:layout_margin="16dp">
@@ -22,13 +29,24 @@
<com.appttude.h_mal.days_left.ui.customViews.CircleView <com.appttude.h_mal.days_left.ui.customViews.CircleView
android:id="@+id/arc_view" android:id="@+id/arc_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:layout_gravity="center" /> 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 <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" 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"> android:orientation="vertical">
<LinearLayout <LinearLayout
@@ -70,9 +88,9 @@
android:textColor="@color/one" android:textColor="@color/one"
android:textSize="16sp" /> android:textSize="16sp" />
</LinearLayout> </LinearLayout>
</FrameLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
</FrameLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

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

View File

@@ -13,114 +13,89 @@
android:layout_marginBottom="6dp" android:layout_marginBottom="6dp"
app:cardCornerRadius="@dimen/card_radius"> app:cardCornerRadius="@dimen/card_radius">
<LinearLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/lin" android:id="@+id/lin"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:layout_margin="16dp" android:padding="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>-->
<com.appttude.h_mal.days_left.ui.customViews.BarView <com.appttude.h_mal.days_left.ui.customViews.BarView
android:id="@+id/bar" android:id="@+id/bar"
android:layout_width="match_parent" 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--> <androidx.constraintlayout.widget.ConstraintLayout
<!--android:id="@+id/bottom_text_holder"--> android:layout_width="0dp"
<!--android:layout_width="match_parent"--> android:layout_height="wrap_content"
<!--android:layout_height="wrap_content"--> android:layout_marginTop="8dp"
<!--android:orientation="horizontal">--> app:layout_constraintTop_toBottomOf="@id/bar"
app:layout_constraintRight_toRightOf="parent"
<!--<TextView--> app:layout_constraintLeft_toLeftOf="parent"
<!--style="@style/text_minor"--> app:layout_constraintBottom_toBottomOf="parent">
<!--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">
<TextView <TextView
style="@style/text_major" android:id="@+id/text_piece_header"
android:layout_width="0dp" android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="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" /> android:text="Piece Rate" />
<TextView <TextView
android:id="@+id/pc_amount_text" android:textAppearance="?android:attr/textAppearanceSmall"
style="@style/text_minor" android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" app:layout_constraintRight_toRightOf="parent"
android:gravity="right" app:layout_constraintTop_toTopOf="@id/text_piece_header"
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"
android:text="Hourly" /> 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> </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"?> <?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:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
xmlns:tools="http://schemas.android.com/tools">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="12dp" android:elevation="0dp"
android:layout_marginTop="6dp" android:layout_margin="12dp"
android:layout_marginRight="12dp" app:cardCornerRadius="@dimen/card_radius"
android:layout_marginBottom="6dp" tools:cardBackgroundColor="#BDBDBD" >
app:cardCornerRadius="@dimen/card_radius"> <androidx.constraintlayout.widget.ConstraintLayout
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:layout_margin="16dp" android:background="?android:attr/selectableItemBackground"
android:orientation="vertical"> android:paddingTop="5dp"
android:paddingBottom="5dp">
<LinearLayout <LinearLayout
android:id="@+id/container_one"
style="@style/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginRight="6dp"
android:layout_weight="1" android:layout_weight="1"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:id="@+id/farm_name" android:id="@+id/item_title"
style="@style/title_card"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:ellipsize="marquee"
android:singleLine="true"
android:textColor="@color/one" android:textColor="@color/one"
android:textSize="22sp" android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
tools:text="W and L Farm" /> tools:text="W and L Farm" />
<TextView <TextView
android:id="@+id/task_name" android:id="@+id/task_name"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:layout_weight="1" android:autoLink="web"
android:gravity="left|center" android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/two" android:textColor="@color/two"
android:textSize="20sp"
tools:text="Packing Tomatoes" /> tools:text="Packing Tomatoes" />
</LinearLayout> </LinearLayout>
<TextView <TextView
android:id="@+id/date" android:id="@+id/date"
style="@style/text_major"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:gravity="top|right" android:gravity="top|right"
android:textColor="@color/two"
android:alpha="0.7"
android:textSize="12sp"
tools:text="19/04/2018" /> tools:text="19/04/2018" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/container_two"
style="@style/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" 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 <ImageView
android:layout_width="30dp" style="@style/container_icon"
android:layout_height="30dp"
android:alpha="0.45"
android:src="@drawable/task" /> android:src="@drawable/task" />
<TextView <TextView
android:id="@+id/type" android:id="@+id/type"
android:layout_width="wrap_content" style="@style/container_subtext"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:gravity="center_vertical"
android:textSize="18sp"
tools:text="Hourly - $23/Hour" /> tools:text="Hourly - $23/Hour" />
</LinearLayout> </LinearLayout>
<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: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 <ImageView
android:layout_width="30dp" style="@style/container_icon"
android:layout_height="30dp"
android:alpha="0.45"
android:src="@drawable/clock_icon" /> android:src="@drawable/clock_icon" />
<TextView <TextView
android:id="@+id/time" android:id="@+id/time"
android:layout_width="wrap_content" style="@style/container_subtext"
android:layout_height="match_parent" tools:text="Hourly - $23/Hour" />
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>
</LinearLayout> </LinearLayout>
<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: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 <ImageView
android:layout_width="30dp" style="@style/container_icon"
android:layout_height="30dp" android:src="@drawable/break_time" />
android:alpha="0.45"
<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" /> android:src="@drawable/box_icon" />
<TextView <TextView
android:id="@+id/units" android:id="@+id/units"
android:layout_width="wrap_content" style="@style/container_subtext"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:gravity="center_vertical"
android:textSize="18sp"
tools:text="6 h 30 m" /> tools:text="6 h 30 m" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/container_six"
style="@style/container"
android:layout_width="match_parent" 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 <ImageView
android:layout_width="30dp" style="@style/container_icon"
android:layout_height="30dp"
android:alpha="0.45"
android:src="@drawable/marker" /> android:src="@drawable/marker" />
<TextView <TextView
android:id="@+id/location" android:id="@+id/location"
android:layout_width="wrap_content" style="@style/container_subtext"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:gravity="center_vertical"
android:textSize="18sp"
tools:text="Bundaberg" /> tools:text="Bundaberg" />
</LinearLayout> </LinearLayout>
</LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
</FrameLayout> </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 <item
android:id="@+id/app_bar_filter" 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:title="Filter"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
app:showAsAction="always"/> app:showAsAction="always" />
<item <item
android:id="@+id/app_bar_soft" 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