- Viewmodels and live data for the data involved

- migrating to kotlin and removal of spaghetti code
- android navigation added
- user authentication section finished
- ui updated for authentication section
This commit is contained in:
2020-07-17 13:36:28 +01:00
parent 66af16b999
commit c476ed556d
46 changed files with 2037 additions and 553 deletions

179
.idea/navEditor.xml generated Normal file
View File

@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="navEditor-manualLayoutAlgorithm2">
<option name="myPositions">
<map>
<entry key="auth_navigation.xml">
<value>
<LayoutPositions>
<option name="myPositions">
<map>
<entry key="forgotPassword">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="1090" />
<option name="y" value="-654" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="loginFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="707" />
<option name="y" value="-640" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="action_loginFragment_to_forgotPassword">
<value>
<LayoutPositions />
</value>
</entry>
<entry key="action_loginFragment_to_mainActivity">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="loginHomeFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="443" />
<option name="y" value="-636" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="action_splashFragment_to_loginFragment">
<value>
<LayoutPositions />
</value>
</entry>
<entry key="to_registrationNicknameFragment">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="mainActivity">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="1094" />
<option name="y" value="-236" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="registrationConfirmationFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="703" />
<option name="y" value="-234" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="action_registrationConfirmationFragment_to_mainActivity">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="registrationEmailFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="444" />
<option name="y" value="101" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="action_registrationEmailFragment_to_registrationPasswordFragment">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="registrationNicknameFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="437" />
<option name="y" value="-236" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="action_registrationNicknameFragment_to_registrationEmailFragment">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="registrationPasswordFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="705" />
<option name="y" value="103" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="action_registrationPasswordFragment_to_registrationConfirmationFragment">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@@ -1,12 +1,13 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
// kotlin kapt // kotlin kapt
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
// google services // google services
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'
// Android navigation
apply plugin: 'androidx.navigation.safeargs'
android { android {
compileSdkVersion 29 compileSdkVersion 29
@@ -54,6 +55,8 @@ 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'
// Testing // Testing
testImplementation 'junit:junit:4.13' testImplementation 'junit:junit:4.13'

View File

@@ -16,18 +16,22 @@
android:supportsRtl="true" android:supportsRtl="true"
android:name=".application.AppClass" android:name=".application.AppClass"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<activity android:name=".AddItemActivity"></activity> <activity android:name=".ui.splashScreen.SplashFragment"
<activity
android:name="com.appttude.h_mal.days_left.ui.login.FullscreenActivity"
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>
<activity
android:name="com.appttude.h_mal.days_left.ui.login.FullscreenActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name"/>
<activity android:name=".AddItemActivity"/>
<activity android:name=".ChangeUserDetailsActivity" /> <activity android:name=".ChangeUserDetailsActivity" />
<activity android:name=".AddShiftActivity" /> <activity android:name=".AddShiftActivity" />
<activity <activity

View File

@@ -0,0 +1,47 @@
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,9 +1,10 @@
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.FirebaseDatabase import com.appttude.h_mal.days_left.ui.login.AuthViewModelFactory
import com.appttude.h_mal.days_left.ui.login.FirebaseAuthSource import com.appttude.h_mal.days_left.data.firebase.FirebaseAuthSource
import com.appttude.h_mal.days_left.ui.login.UserRepository import com.appttude.h_mal.days_left.data.firebase.FirebaseDataSource
import com.appttude.h_mal.days_left.data.repository.UserRepository
import com.appttude.h_mal.days_left.ui.main.MainViewModelFactory import com.appttude.h_mal.days_left.ui.main.MainViewModelFactory
import com.appttude.h_mal.days_left.ui.main.ShiftsViewModelFactory import com.appttude.h_mal.days_left.ui.main.ShiftsViewModelFactory
import org.kodein.di.Kodein import org.kodein.di.Kodein
@@ -20,17 +21,18 @@ class AppClass : Application(), KodeinAware{
import(androidXModule(this@AppClass)) import(androidXModule(this@AppClass))
bind() from singleton { FirebaseAuthSource() } bind() from singleton { FirebaseAuthSource() }
bind() from singleton { FirebaseDatabase() } bind() from singleton { FirebaseDataSource() }
bind() from singleton { UserRepository(instance()) } bind() from singleton {
bind() from provider { UserRepository(
MainViewModelFactory(
instance() instance()
) )
} }
bind() from provider { MainViewModelFactory( instance() ) }
bind() from provider { bind() from provider {
ShiftsViewModelFactory( ShiftsViewModelFactory( instance() )
instance() }
) bind() from provider {
AuthViewModelFactory( instance() )
} }
} }
} }

View File

@@ -1,7 +1,10 @@
package com.appttude.h_mal.days_left package com.appttude.h_mal.days_left.data.firebase
import com.appttude.h_mal.days_left.FirebaseClass
import com.appttude.h_mal.days_left.FirebaseClass.Companion.auth import com.appttude.h_mal.days_left.FirebaseClass.Companion.auth
import com.appttude.h_mal.days_left.FirebaseClass.Companion.mDatabase import com.appttude.h_mal.days_left.FirebaseClass.Companion.mDatabase
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase
const val USER_FIREBASE = "users" const val USER_FIREBASE = "users"
val EMPLOYER_FIREBASE = "employers" val EMPLOYER_FIREBASE = "employers"
@@ -12,10 +15,19 @@ val SHIFT_ID = "shift_id"
val PIECE = "Piece Rate" val PIECE = "Piece Rate"
val HOURLY = "Hourly" val HOURLY = "Hourly"
class FirebaseDatabase{ class FirebaseDataSource{
fun allShifts() = mDatabase.child(USER_FIREBASE).child(auth.uid!!).child(SHIFT_FIREBASE) private val firebaseDatabase: FirebaseDatabase by lazy {
fun child(shiftId: String) = mDatabase.child(USER_FIREBASE).child(auth.uid!!).child(SHIFT_FIREBASE).child(shiftId) FirebaseDatabase.getInstance()
}
private val mDatabase = firebaseDatabase.reference
fun allShifts() = mDatabase.child(USER_FIREBASE).child(auth.uid!!).child(
SHIFT_FIREBASE
)
fun child(shiftId: String) = mDatabase.child(USER_FIREBASE).child(auth.uid!!).child(
SHIFT_FIREBASE
).child(shiftId)
fun taskObject(abn: String) = mDatabase.child(FirebaseClass.EMPLOYER_FIREBASE).child(abn).child( fun taskObject(abn: String) = mDatabase.child(FirebaseClass.EMPLOYER_FIREBASE).child(abn).child(
FirebaseClass.TASK_FIREBASE FirebaseClass.TASK_FIREBASE

View File

@@ -0,0 +1,34 @@
package com.appttude.h_mal.days_left.data.firebase
import com.google.android.gms.tasks.Task
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.functions.FirebaseFunctions
import com.google.firebase.functions.HttpsCallableResult
import java.util.HashMap
class FirebaseFunctionsSource {
private val functions: FirebaseFunctions by lazy {
FirebaseFunctions.getInstance()
}
fun getAbnList(input: String): Task<HttpsCallableResult> {
val data = HashMap<String, Any>()
data["input"] = input
data["push"] = true
return functions
.getHttpsCallable("abnLooKUp")
.call(data)
}
fun getExcel(): Task<HttpsCallableResult> {
// Create the arguments to the callable function.
val data = HashMap<String, Any>()
data["push"] = true
return functions
.getHttpsCallable("writeFireToExcelVisa")
.call(data)
}
}

View File

@@ -0,0 +1,20 @@
package com.appttude.h_mal.days_left.firebaseUtils
import com.google.android.gms.tasks.Task
import java.io.IOException
abstract class FirebaseExtraction {
fun <T : Any> safeFirebaseResult(
call: () -> Task<T>
): T {
val task = call.invoke()
if (!task.isSuccessful) {
throw task.exception ?: IOException("Failed to complete firebase task")
} else {
return task.result!!
}
}
}

View File

@@ -1,4 +1,4 @@
package com.appttude.h_mal.days_left.firebaseLiveData package com.appttude.h_mal.days_left.firebaseUtils
import android.util.Log import android.util.Log
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData

View File

@@ -0,0 +1,10 @@
package com.appttude.h_mal.days_left.models
/**
* Data validation state of the login form.
*/
data class LoginFormState(
val usernameError: Int? = null,
val passwordError: Int? = null,
val isDataValid: Boolean = false
)

View File

@@ -0,0 +1,24 @@
package com.appttude.h_mal.days_left.models.liveData
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,38 @@
package com.appttude.h_mal.days_left.models.registration
import android.os.Parcel
import android.os.Parcelable
data class RegistrationArgs(
var name: String? = null,
var email: String? = null,
var password: String? = null
): Parcelable{
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readString(),
parcel.readString()
) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(name)
parcel.writeString(email)
parcel.writeString(password)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<RegistrationArgs> {
override fun createFromParcel(parcel: Parcel): RegistrationArgs {
return RegistrationArgs(parcel)
}
override fun newArray(size: Int): Array<RegistrationArgs?> {
return arrayOfNulls(size)
}
}
}

View File

@@ -2,7 +2,7 @@ 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.FirebaseDatabase import com.appttude.h_mal.days_left.data.repository.UserRepository
/** /**
* ViewModel provider factory to instantiate LoginViewModel. * ViewModel provider factory to instantiate LoginViewModel.

View File

@@ -5,13 +5,22 @@ 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.view.inputmethod.EditorInfo
import androidx.fragment.app.activityViewModels
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.FullscreenActivity.Companion.fragmentManagerLogin import com.appttude.h_mal.days_left.utils.afterTextChanged
import kotlinx.android.synthetic.main.fragment_forgot_password.* import com.appttude.h_mal.days_left.utils.isEmailValid
import com.appttude.h_mal.days_left.utils.navigateTo
import com.appttude.h_mal.days_left.utils.showToast
import kotlinx.android.synthetic.main.fragment_forgot_password.submission_et
import kotlinx.android.synthetic.main.fragment_forgot_password.til_submission
class ForgotPassword : Fragment(), ForgotPasswordCallback { class ForgotPassword : Fragment() {
val viewModel: AuthViewModel by activityViewModels()
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
@@ -21,24 +30,39 @@ class ForgotPassword : Fragment(), ForgotPasswordCallback {
return inflater.inflate(R.layout.fragment_forgot_password, container, false) return inflater.inflate(R.layout.fragment_forgot_password, container, false)
} }
override fun onStarted() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
pb.visibility = View.VISIBLE super.onViewCreated(view, savedInstanceState)
submission_et.apply{
afterTextChanged {
til_submission.error = null
} }
override fun onEmailInvalid() { setOnEditorActionListener { _, id, _ ->
pb.visibility = View.GONE if (id == EditorInfo.IME_ACTION_DONE) {
reset_pw.error = getString(R.string.error_invalid_password) resetPassword()
return@setOnEditorActionListener true
}
false
}
} }
override fun onSuccess() { viewModel.operationResetPassword.observe(viewLifecycleOwner, Observer {
pb.visibility = View.GONE it.getContentIfNotHandled()?.let {
fragmentManagerLogin.popBackStack() context?.let {ctx ->
ctx.showToast(ctx.resources.getString(R.string.password_reset_success))
activity?.onBackPressed()
}
}
})
} }
override fun onFailure(message: String) { private fun resetPassword(){
pb.visibility = View.GONE val email = submission_et.text.toString()
Toast.makeText(context,message,Toast.LENGTH_LONG).show() if (!isEmailValid(email)){
til_submission.error = "Not a valid email address"
return
}
viewModel.resetPassword(email)
} }
} }

View File

@@ -2,38 +2,55 @@ package com.appttude.h_mal.days_left.ui.login
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import androidx.activity.viewModels
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
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.FirebaseClass.Companion.auth import com.appttude.h_mal.days_left.ui.splashScreen.SplashFragment
import com.google.firebase.auth.FirebaseAuth import com.appttude.h_mal.days_left.utils.hide
import com.appttude.h_mal.days_left.utils.show
import com.appttude.h_mal.days_left.utils.showToast
import kotlinx.android.synthetic.main.activity_fullscreen.*
import org.kodein.di.KodeinAware
import org.kodein.di.android.kodein
import org.kodein.di.generic.instance
class FullscreenActivity : AppCompatActivity() { class FullscreenActivity : AppCompatActivity(), KodeinAware {
companion object { override val kodein by kodein()
lateinit var fragmentManagerLogin : FragmentManager private val factory by instance<AuthViewModelFactory>()
} private val viewModel: AuthViewModel by viewModels { factory }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_fullscreen) setContentView(R.layout.activity_fullscreen)
auth = FirebaseAuth.getInstance() viewModel.operationState.observe(this, Observer {
if (it){
progress_circular.show()
}else{
progress_circular.hide()
}
})
fragmentManagerLogin = supportFragmentManager viewModel.operationResult.observe(this, Observer {
it.getContentIfNotHandled()?.let { message ->
fragmentManagerLogin.beginTransaction().replace( showToast(message)
R.id.container, }
SplashFragment() })
).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit()
} }
// If the there is more than 1 fragment in the backstack
// Go back to previous fragment
// Or exit
override fun onBackPressed() { override fun onBackPressed() {
container.childFragmentManager.backStackEntryCount.let {
if (it > 0) {
super.onBackPressed() super.onBackPressed()
if (fragmentManagerLogin.fragments.size > 1) { } else {
fragmentManagerLogin.popBackStack() finish()
}
} }
} }
} }

View File

@@ -1,25 +1,23 @@
package com.appttude.h_mal.days_left.ui.login package com.appttude.h_mal.days_left.ui.login
import android.content.Intent
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 android.widget.TextView import androidx.fragment.app.Fragment
import android.widget.Toast
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
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.FullscreenActivity.Companion.fragmentManagerLogin import com.appttude.h_mal.days_left.utils.afterTextChanged
import com.appttude.h_mal.days_left.ui.main.MainActivity 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 import org.kodein.di.generic.instance
class LoginFragment : Fragment(), LoginCallback, KodeinAware { class LoginFragment : Fragment(), KodeinAware {
override val kodein by kodein() override val kodein by kodein()
private val factory by instance<AuthViewModelFactory>() private val factory by instance<AuthViewModelFactory>()
private val viewModel: AuthViewModel by viewModels { factory } private val viewModel: AuthViewModel by viewModels { factory }
@@ -34,57 +32,46 @@ class LoginFragment : Fragment(), LoginCallback, KodeinAware {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
password.setOnEditorActionListener(TextView.OnEditorActionListener { textView, id, keyEvent -> password.apply {
if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) { setOnEditorActionListener { textView, id, _ ->
viewModel.onClickLogin(textView) if (id == EditorInfo.IME_ACTION_DONE) {
return@OnEditorActionListener true viewModel.login(
submission_et.text.toString(),
textView.text.toString()
)
return@setOnEditorActionListener true
} }
false false
}
afterTextChanged {
til_password.error = null
}
}
submission_et.apply {
afterTextChanged {
til_submission.error = null
}
}
viewModel.loginFormState.observe(viewLifecycleOwner, Observer {
val loginState = it ?: return@Observer
if (loginState.usernameError != null) {
til_submission.error = getString(loginState.usernameError)
}
if (loginState.passwordError != null) {
til_password.error = getString(loginState.passwordError)
}
}) })
forgot.setOnClickListener{ viewModel.operationLogin.observe(viewLifecycleOwner, Observer {
fragmentManagerLogin.beginTransaction() it.getContentIfNotHandled()?.let {
.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_in) view.navigateTo(R.id.LoginTo_mainActivity)
.replace(R.id.container, ForgotPassword())
.addToBackStack("forgot_pw").commit()
} }
})
register_button.setOnClickListener {
fragmentManagerLogin.beginTransaction()
.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_in)
.replace(R.id.container, Register())
.addToBackStack("register")
.commit()
}
}
override fun onStarted() {
login_progress.visibility = View.VISIBLE
}
override fun onEmailInvalid() {
email.error = getString(R.string.error_invalid_email)
email.requestFocus()
login_progress.visibility = View.GONE
}
override fun onPasswordInvalid() {
password.error = getString(R.string.error_invalid_password)
password.requestFocus()
login_progress.visibility = View.GONE
}
override fun onSuccess() {
login_progress.visibility = View.GONE
Intent(context, MainActivity::class.java).apply {
startActivity(this)
activity?.finish()
}
}
override fun onFailure(message: String) {
Toast.makeText(context,message,Toast.LENGTH_LONG).show()
login_progress.visibility = View.GONE
} }
} }

View File

@@ -0,0 +1,45 @@
package com.appttude.h_mal.days_left.ui.login
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_login_home.*
/**
* A simple [Fragment] subclass.
* create an instance of this fragment.
*/
class LoginHomeFragment : Fragment(), View.OnClickListener {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_login_home, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
sign_up.setOnClickListener(this)
submission_button.setOnClickListener(this)
}
override fun onClick(v: View) {
when(v.id){
R.id.sign_up -> R.id.to_registrationNicknameFragment
R.id.submission_button -> R.id.splash_to_loginFragment
else ->{
null
}
}?.let {
view?.navigateTo(it)
}
}
}

View File

@@ -1,73 +0,0 @@
package com.appttude.h_mal.days_left.ui.login
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.lifecycle.ViewModelProviders
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.main.MainActivity
import kotlinx.android.synthetic.main.fragment_register.*
class Register : Fragment(), RegisterCallBack {
val viewModel = ViewModelProviders.of(this).get(RegisterViewModel::class.java)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_register, container, false)
}
override fun onStarted() {
pb.visibility = View.VISIBLE
}
override fun onNameInvalid() {
pb.visibility = View.GONE
name_register.error = getString(R.string.error_invalid_email)
name_register.requestFocus()
}
override fun onEmailInvalid() {
pb.visibility = View.GONE
email_register.error = getString(R.string.error_invalid_email)
email_register.requestFocus()
}
override fun onPasswordInvalid(id: Int) {
pb.visibility = View.GONE
when(id){
0 -> password_top.error = getString(R.string.error_invalid_password)
1 -> password_top.error = getString(R.string.no_match_password)
}
password_top.requestFocus()
}
override fun onPasswordTwoInvalid() {
pb.visibility = View.GONE
password_bottom.error = getString(R.string.error_invalid_password)
password_bottom.requestFocus()
}
override fun onSuccess() {
pb.visibility = View.GONE
Intent(context, MainActivity::class.java).apply {
this.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(this)
activity?.finish()
}
}
override fun onFailure(message: String) {
pb.visibility = View.GONE
Toast.makeText(context,message,Toast.LENGTH_LONG).show()
}
}

View File

@@ -0,0 +1,82 @@
package com.appttude.h_mal.days_left.ui.login.registration
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.ui.login.AuthViewModel
import com.appttude.h_mal.days_left.utils.afterTextChanged
import com.appttude.h_mal.days_left.utils.isEmailValid
import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_registration_four.*
import kotlinx.android.synthetic.main.fragment_registration_four.submission_button
import kotlinx.android.synthetic.main.fragment_registration_four.submission_et
import kotlinx.android.synthetic.main.fragment_registration_four.til_submission
import kotlinx.android.synthetic.main.fragment_registration_two.*
/**
* A simple [Fragment] subclass.
* Use the [RegistrationFourFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class RegistrationConfirmationFragment : Fragment() {
val viewmodel: AuthViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_registration_four, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
submission_et.apply {
afterTextChanged {
til_submission.error = null
}
setOnEditorActionListener { textView, id, _ ->
if (id == EditorInfo.IME_ACTION_DONE) {
next()
return@setOnEditorActionListener true
}
false
}
}
submission_button.setOnClickListener { next() }
viewmodel.operationRegister.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let {
view.navigateTo(R.id.registration_to_mainActivity)
}
})
}
fun next(){
val password = submission_et.text.toString()
val regArgs =
RegistrationConfirmationFragmentArgs.fromBundle(requireArguments()).regThreeArgs
val previousPassword = regArgs.password!!
if (password != previousPassword){
til_submission.error = "Passwords do not match"
return
}
regArgs.run {
viewmodel.register(
email!!, previousPassword, name!!
)
}
}
}

View File

@@ -0,0 +1,72 @@
package com.appttude.h_mal.days_left.ui.login.registration
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.models.registration.RegistrationArgs
import com.appttude.h_mal.days_left.utils.afterTextChanged
import com.appttude.h_mal.days_left.utils.isEmailValid
import com.appttude.h_mal.days_left.utils.isNameValid
import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_registration_two.*
/**
* A simple [Fragment] subclass.
* Use the [RegistrationEmailFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class RegistrationEmailFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_registration_two, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
submission_et.apply {
afterTextChanged {
til_submission.error = null
}
setOnEditorActionListener { textView, id, _ ->
if (id == EditorInfo.IME_ACTION_DONE) {
next()
return@setOnEditorActionListener true
}
false
}
}
submission_button.setOnClickListener { next() }
}
fun next(){
val email = submission_et.text.toString()
if (!isEmailValid(email)){
til_submission.error = "Enter a valid Email"
return
}
val regArgs =
RegistrationEmailFragmentArgs.fromBundle(requireArguments()).regOneArgs
regArgs.email = email
val action =
RegistrationEmailFragmentDirections.toRegistrationPasswordFragment(regArgs)
view?.navigateTo(action)
}
}

View File

@@ -0,0 +1,67 @@
package com.appttude.h_mal.days_left.ui.login.registration
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import 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.isNameValid
import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_nickname.*
/**
* A simple [Fragment] subclass.
* Use the [RegistrationNicknameFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class RegistrationNicknameFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_nickname, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
submission_et.apply {
afterTextChanged {
til_submission.error = null
}
setOnEditorActionListener { textView, id, _ ->
if (id == EditorInfo.IME_ACTION_DONE) {
next()
return@setOnEditorActionListener true
}
false
}
}
submission_button.setOnClickListener { next() }
}
fun next(){
val name = submission_et.text.toString()
if (!isNameValid(name)){
til_submission.error = "Enter a valid Nickname"
return
}
val regArgs = RegistrationArgs(name)
val action =
RegistrationNicknameFragmentDirections.toRegistrationEmail(regArgs)
view?.navigateTo(action)
}
}

View File

@@ -0,0 +1,71 @@
package com.appttude.h_mal.days_left.ui.login.registration
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import com.appttude.h_mal.days_left.R
import com.appttude.h_mal.days_left.utils.afterTextChanged
import com.appttude.h_mal.days_left.utils.isEmailValid
import com.appttude.h_mal.days_left.utils.isPasswordValid
import com.appttude.h_mal.days_left.utils.navigateTo
import kotlinx.android.synthetic.main.fragment_registration_password.*
/**
* A simple [Fragment] subclass.
* Use the [RegistrationPasswordFragment] factory method to
* create an instance of this fragment.
*/
class RegistrationPasswordFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_registration_password, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
submission_et.apply {
afterTextChanged {
til_submission.error = null
}
setOnEditorActionListener { textView, id, _ ->
if (id == EditorInfo.IME_ACTION_DONE) {
next()
return@setOnEditorActionListener true
}
false
}
}
submission_button.setOnClickListener { next() }
}
fun next(){
val password = submission_et.text.toString()
if (!isPasswordValid(password)){
til_submission.error = "Enter a valid Email"
return
}
val regArgs =
RegistrationPasswordFragmentArgs.fromBundle(requireArguments()).regTwoArgs
regArgs.password = password
val action =
RegistrationPasswordFragmentDirections.toRegistrationConfirmationFragment(regArgs)
view?.navigateTo(action)
}
}

View File

@@ -9,6 +9,8 @@ import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat import androidx.core.view.GravityCompat
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider
import com.appttude.h_mal.days_left.* import com.appttude.h_mal.days_left.*
import com.appttude.h_mal.days_left.ui.login.FullscreenActivity import com.appttude.h_mal.days_left.ui.login.FullscreenActivity
import com.appttude.h_mal.days_left.FirebaseClass.Companion.SHIFT_FIREBASE import com.appttude.h_mal.days_left.FirebaseClass.Companion.SHIFT_FIREBASE
@@ -26,11 +28,13 @@ import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.nav_header_main.view.* 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<MainViewModelFactory>()
private val factory2 by instance<ShiftsViewModelFactory>()
val viewModel: MainViewModel by viewModels{ factory } val viewModel: MainViewModel by viewModels{ factory }
companion object{ companion object{
@@ -42,6 +46,8 @@ class MainActivity : AppCompatActivity(), KodeinAware {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_drawer_main) setContentView(R.layout.activity_drawer_main)
ViewModelProvider(this, factory2).get(ShiftsViewModel::class.java)
//setup backstack change listener //setup backstack change listener
supportFragmentManager.addOnBackStackChangedListener(backStackChangedListener) supportFragmentManager.addOnBackStackChangedListener(backStackChangedListener)
//set toolbar //set toolbar

View File

@@ -2,7 +2,7 @@ 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.ui.login.UserRepository import com.appttude.h_mal.days_left.data.repository.UserRepository
/** /**
* ViewModel provider factory to instantiate LoginViewModel. * ViewModel provider factory to instantiate LoginViewModel.

View File

@@ -1,14 +1,88 @@
package com.appttude.h_mal.days_left.ui.main package com.appttude.h_mal.days_left.ui.main
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.appttude.h_mal.days_left.FirebaseDatabase import com.appttude.h_mal.days_left.data.firebase.FirebaseDataSource
import com.appttude.h_mal.days_left.firebaseLiveData.FirebaseQueryLiveData import com.appttude.h_mal.days_left.firebaseUtils.FirebaseQueryLiveData
import com.appttude.h_mal.days_left.models.ShiftObject
import com.google.firebase.database.DataSnapshot
import java.util.HashSet
class ShiftsViewModel( class ShiftsViewModel(
val database: FirebaseDatabase val database: FirebaseDataSource
): ViewModel() { ): ViewModel() {
private val shifts = database.allShifts() val shifts = database.allShifts()
val shiftData = FirebaseQueryLiveData(shifts) val shiftData = FirebaseQueryLiveData(shifts)
val liveData = MutableLiveData<Triple<List<ShiftObject?>, Int, IntArray>>()
init {
shiftData.observeForever {
val list = it.mapSnapToShiftList()
val uniqueEntries = countDistinct(list)
val shiftTypeCount = countShiftType(list)
liveData.value = Triple(
list,
uniqueEntries,
shiftTypeCount
)
}
}
private fun countDistinct(list: List<ShiftObject?>): Int {
return list.distinctBy { it?.shiftDate }.size
}
private fun countShiftType(list: List<ShiftObject?>): IntArray {
val i = list.filter { it?.taskObject?.workType.equals("Hourly") }.size
val j = list.size - i
return intArrayOf(i, j)
}
private fun DataSnapshot.mapSnapToShiftList(): List<ShiftObject?> = this.children.map {
it.getValue(ShiftObject::class.java)
}
// private fun calculateAccumulatedPay(type: Int): Float {
// var pay = 0f
//
// for (shiftObject in shiftList) {
// shiftObject?.let {
// when (type){
// 0 -> {
// if (it.taskObject?.workType == "Hourly") {
// pay += it.taskObject?.rate?.times((it.timeObject!!.hours - it.timeObject!!.breakEpoch))
// ?: pay
// }
// }
// 1 -> {
// if (it.taskObject?.workType == "Piece Rate") {
// pay += it.taskObject?.rate?.times(it.unitsCount!!) ?: pay
// }
// }
// else -> {
// if (it.taskObject?.workType == "Hourly") {
// pay += it.taskObject?.rate?.times((it.timeObject!!.hours - it.timeObject!!.breakEpoch))
// ?: pay
// } else {
// pay += it.taskObject?.rate?.times(it.unitsCount!!) ?: pay
// }
// }
// }
// }
// }
//
// return pay
// }
private fun totalPay(): Float{
return 0.0f
}
} }

View File

@@ -2,14 +2,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.FirebaseDatabase import com.appttude.h_mal.days_left.data.firebase.FirebaseDataSource
/** /**
* 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: FirebaseDatabase private val firebaseDatabase: FirebaseDataSource
) : ViewModelProvider.Factory { ) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")

View File

@@ -4,24 +4,31 @@ import android.app.AlertDialog
import android.content.DialogInterface import android.content.DialogInterface
import android.content.DialogInterface.BUTTON_POSITIVE 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 android.widget.AdapterView
import androidx.fragment.app.activityViewModels
import com.appttude.h_mal.days_left.* import com.appttude.h_mal.days_left.*
import com.appttude.h_mal.days_left.ui.main.MainActivity
import com.appttude.h_mal.days_left.CustomDialog.Companion.dateSelectionFrom import com.appttude.h_mal.days_left.CustomDialog.Companion.dateSelectionFrom
import com.appttude.h_mal.days_left.CustomDialog.Companion.dateSelectionTo import com.appttude.h_mal.days_left.CustomDialog.Companion.dateSelectionTo
import com.appttude.h_mal.days_left.ui.main.MainActivity.Companion.ref
import com.appttude.h_mal.days_left.FirebaseClass.Companion.SHIFT_ID import com.appttude.h_mal.days_left.FirebaseClass.Companion.SHIFT_ID
import com.appttude.h_mal.days_left.models.AbnObject import com.appttude.h_mal.days_left.models.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.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.firebase.ui.database.FirebaseRecyclerAdapter
import com.google.firebase.FirebaseOptions
import com.google.firebase.database.Query import com.google.firebase.database.Query
import kotlinx.android.synthetic.main.dialog_previous_abns_used.view.* import kotlinx.android.synthetic.main.dialog_previous_abns_used.view.*
import kotlinx.android.synthetic.main.fragment_list.* import kotlinx.android.synthetic.main.fragment_list.*
import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
class FragmentList : androidx.fragment.app.Fragment() { class FragmentList : androidx.fragment.app.Fragment() {
val viewModel: ShiftsViewModel by activityViewModels()
lateinit var fireAdapter: FireAdapter lateinit var fireAdapter: FireAdapter
@@ -35,41 +42,41 @@ class FragmentList : androidx.fragment.app.Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
//set custom firebase adapter on listview //set custom firebase adapter on listview
fireAdapter = FireAdapter( fireAdapter = FireAdapter(
activity, activity,
ShiftObject::class.java, ShiftObject::class.java,
R.layout.list_item, R.layout.list_item,
ref viewModel.shifts
) )
page_two_list.adapter = fireAdapter
page_two_list.setOnItemClickListener(object : AdapterView.OnItemClickListener{ page_two_list.apply {
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { adapter = fireAdapter
onItemClickListener =
AdapterView.OnItemClickListener { _, _, position, _ ->
val refId = fireAdapter.getId(position) val refId = fireAdapter.getId(position)
val intent = Intent(activity, AddShiftActivity::class.java) val intent = Intent(activity, AddShiftActivity::class.java)
intent.putExtra(SHIFT_ID, refId) intent.putExtra(SHIFT_ID, refId)
startActivity(intent) startActivity(intent)
} }
})
page_two_list.setOnItemLongClickListener(object : AdapterView.OnItemLongClickListener{
override fun onItemLongClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long): Boolean {
val builder = AlertDialog.Builder(context)
builder.setTitle("Are you sure you want to delete?")
builder.setNegativeButton(android.R.string.no, null)
builder.setPositiveButton(
android.R.string.yes
) { dialog, which ->
onItemLongClickListener =
AdapterView.OnItemLongClickListener { _, _, position, _ ->
AlertDialog.Builder(context).apply {
setTitle("Are you sure you want to delete?")
setNegativeButton(android.R.string.no, null)
setPositiveButton(android.R.string.yes) { _, _ ->
fireAdapter.getRef(position).removeValue() fireAdapter.getRef(position).removeValue()
} }
builder.create().show() create().show()
return false
} }
}) true
}
}
setHasOptionsMenu(true)
} }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater) super.onCreateOptionsMenu(menu, inflater)
@@ -77,7 +84,7 @@ class FragmentList : androidx.fragment.app.Fragment() {
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.getItemId()) { when (item.itemId) {
R.id.app_bar_filter -> { R.id.app_bar_filter -> {
filterData() filterData()
return false return false
@@ -91,21 +98,24 @@ class FragmentList : androidx.fragment.app.Fragment() {
} }
private fun sortData() { private fun sortData() {
val grpname = arrayOf("Name", "Date Added", "Date of shift") val groupName = arrayOf("Name", "Date Added", "Date of shift")
val checkedItem = -1 val checkedItem = -1
val alt_bld = AlertDialog.Builder(context) AlertDialog.Builder(context).apply {
alt_bld.setTitle("Sort by:") setTitle("Sort by:")
alt_bld.setSingleChoiceItems(grpname, checkedItem) { dialog, item -> setSingleChoiceItems(groupName, checkedItem) { dialog, item ->
when (item) { when (item) {
0 -> { 0 -> {
val q1 = ref.orderByChild("abnObject/companyName").equalTo("GREEN CLOUD NURSERY") val q1 =
fireAdapter = FireAdapter(
activity, viewModel.shifts.orderByChild("abnObject/companyName").equalTo("GREEN CLOUD NURSERY")
ShiftObject::class.java, fireAdapter.notifyDataSetChanged()
R.layout.list_item, // fireAdapter = FireAdapter(
q1 // activity,
) // ShiftObject::class.java,
// R.layout.list_item,
// q1
// )
} }
1 -> fireAdapter = FireAdapter( 1 -> fireAdapter = FireAdapter(
activity, activity,
@@ -123,7 +133,9 @@ class FragmentList : androidx.fragment.app.Fragment() {
page_two_list.adapter = fireAdapter page_two_list.adapter = fireAdapter
dialog.dismiss() dialog.dismiss()
} }
alt_bld.create().show() create().show()
}
} }
private fun filterData() { private fun filterData() {
@@ -132,7 +144,10 @@ class FragmentList : androidx.fragment.app.Fragment() {
val builder = AlertDialog.Builder(context) val builder = AlertDialog.Builder(context)
builder.setTitle("Filter by:") builder.setTitle("Filter by:")
builder.setSingleChoiceItems(groupName,checkedItem, DialogInterface.OnClickListener{dialog, item -> builder.setSingleChoiceItems(
groupName,
checkedItem,
DialogInterface.OnClickListener { dialog, item ->
dialog.dismiss() dialog.dismiss()
when (item) { when (item) {
@@ -140,8 +155,10 @@ class FragmentList : androidx.fragment.app.Fragment() {
val dialogBuilder = AlertDialog.Builder(context) val dialogBuilder = AlertDialog.Builder(context)
dialogBuilder.setTitle("Select Employer:") dialogBuilder.setTitle("Select Employer:")
//get layout //get layout
val dialogView = View.inflate(context, val dialogView = View.inflate(
R.layout.dialog_previous_abns_used, null) context,
R.layout.dialog_previous_abns_used, null
)
//hide button //hide button
dialogView.button_list_dialog.visibility = View.GONE dialogView.button_list_dialog.visibility = View.GONE
//get listview //get listview
@@ -151,7 +168,7 @@ class FragmentList : androidx.fragment.app.Fragment() {
//populate list in view //populate list in view
listView.adapter = listView.adapter =
AbnListAdapter( AbnListAdapter(
context!!, requireContext(),
uniqueAbnObjects as MutableList<AbnObject> uniqueAbnObjects as MutableList<AbnObject>
) )
//on item click listener //on item click listener
@@ -166,9 +183,10 @@ class FragmentList : androidx.fragment.app.Fragment() {
} }
1 -> { 1 -> {
val customDialog = val customDialog =
CustomDialog(context!!) CustomDialog(requireContext())
customDialog.setButton(BUTTON_POSITIVE, getContext()?.getString(android.R.string.yes), customDialog.setButton(BUTTON_POSITIVE,
getContext()?.getString(android.R.string.yes),
DialogInterface.OnClickListener { dialogNew, which -> DialogInterface.OnClickListener { dialogNew, which ->
//interface results back //interface results back
if (dateSelectionFrom != dateSelectionTo) { if (dateSelectionFrom != dateSelectionTo) {
@@ -187,7 +205,8 @@ class FragmentList : androidx.fragment.app.Fragment() {
typeDialog.setSingleChoiceItems( typeDialog.setSingleChoiceItems(
arrayOf("Hourly", "Piece Rate"), -1 arrayOf("Hourly", "Piece Rate"), -1
) { dialog, which -> ) { dialog, which ->
val q1 = ref.orderByChild("taskObject/workType").equalTo(typeString[which]) val q1 =
ref.orderByChild("taskObject/workType").equalTo(typeString[which])
fireAdapter = FireAdapter( fireAdapter = FireAdapter(
activity, activity,

View File

@@ -0,0 +1,25 @@
package com.appttude.h_mal.days_left.utils
import android.text.TextUtils
import java.util.regex.Pattern
// Password must contain 8-16 characters,
// including at least 1 upper case letter and at least 1 numerical digit.
fun isPasswordValid(password: String?): Boolean {
return password?.let {
Pattern.compile("^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).{8,}\$").matcher(it).find()
} ?: false
}
fun isNameValid(name: String?): Boolean {
return name?.let {
Pattern.compile("[a-zA-Z]{4,}(?: [a-zA-Z]+){0,2}\$").matcher(it).find()
} ?: false
}
fun isEmailValid(email: String?): Boolean {
return email?.let {
android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
} ?: false
}

View File

@@ -11,6 +11,8 @@ import android.widget.EditText
import android.widget.ImageView import android.widget.ImageView
import android.widget.Toast import android.widget.Toast
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.navigation.NavDirections
import androidx.navigation.Navigation
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import java.lang.Exception import java.lang.Exception
@@ -35,18 +37,18 @@ fun Context.hideKeyboard(view: View?) {
inputMethodManager.hideSoftInputFromWindow(view?.windowToken, 0) inputMethodManager.hideSoftInputFromWindow(view?.windowToken, 0)
} }
//fun View.navigateTo(navigationId: Int) { fun View.navigateTo(navigationId: Int) {
// try { try {
// Navigation.findNavController(this).navigate(navigationId) Navigation.findNavController(this).navigate(navigationId)
// }catch (e: IllegalArgumentException){ }catch (e: IllegalArgumentException){
// e.printStackTrace() e.printStackTrace()
// } }
//
//} }
//
//fun View.navigateTo(navDirections: NavDirections) { fun View.navigateTo(navDirections: NavDirections) {
// Navigation.findNavController(this).navigate(navDirections) Navigation.findNavController(this).navigate(navDirections)
//} }
fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) { fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
this.addTextChangedListener(object : TextWatcher { this.addTextChangedListener(object : TextWatcher {

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -1,14 +1,35 @@
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.appttude.h_mal.days_left.Login.FullscreenActivity"> tools:context=".ui.login.FullscreenActivity">
<FrameLayout
<fragment
android:id="@+id/container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:id="@+id/container"> app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/auth_navigation"
tools:context=".ui.auth.AuthActivity" />
</FrameLayout> <ProgressBar
android:id="@+id/progress_circular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
</FrameLayout> android:visibility="gone"
android:elevation="0.2dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,5 +1,5 @@
<?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"
@@ -9,21 +9,32 @@
android:paddingTop="@dimen/activity_vertical_margin" android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".AddItems.AddEmployerFragment"> tools:context=".AddItemActivity">
<ProgressBar <ProgressBar
android:id="@+id/spinning_pb" android:id="@+id/spinning_pb"
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:layout_centerInParent="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<LinearLayout <LinearLayout
android:id="@+id/empty_list" android:id="@+id/empty_list"
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:layout_centerInParent="true"
android:orientation="vertical">
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 <ImageView
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -45,23 +56,16 @@
android:textSize="16sp" /> android:textSize="16sp" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/search_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/search_button"
android:orientation="vertical">
<ListView <ListView
android:id="@+id/list_view" android:id="@+id/list_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginBottom="16dp" android:layout_weight="1"
android:layout_weight="1"> app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
</ListView> app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</LinearLayout>
</RelativeLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,9 +1,43 @@
<?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: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"
tools:context="com.appttude.h_mal.days_left.Login.BlankFragment" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:background="@drawable/splash"> android:background="@drawable/splash">
</FrameLayout> <ImageView
android:id="@+id/logo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="48dp"
android:layout_marginEnd="24dp"
android:adjustViewBounds="true"
android:src="@drawable/farmicon_round"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.2"
app:layout_constraintWidth_percent=".40"/>
<TextView
android:id="@+id/app_name_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="@id/logo"
app:layout_constraintRight_toRightOf="@id/logo"
app:layout_constraintBottom_toTopOf="@id/logo"
android:gravity="center"
android:textStyle="bold"
android:textSize="36sp"
android:textColor="@android:color/white"
android:text="@string/app_name"
android:layout_marginBottom="12dp"
app:layout_constraintWidth_percent=".40"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,66 +1,89 @@
<?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:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@drawable/spash_drawable" android:background="@android:color/white"
tools:context="com.appttude.h_mal.days_left.Login.ForgotPassword"> 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.login.FullscreenActivity">
<RelativeLayout <TextView
android:layout_width="match_parent" android:id="@+id/forgotPassword"
android:layout_height="match_parent" style="@style/title_text"
tools:context=".User.RegisterActivity"> android:layout_width="0dp"
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/pb" android:layout_marginStart="24dp"
android:visibility="gone"/> android:layout_marginTop="96dp"
android:layout_marginEnd="24dp"
android:text="@string/forgot_password"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout <TextView
android:layout_width="match_parent" android:id="@+id/forgotPassword_subtitle_tv"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" android:layout_marginStart="24dp"
android:layout_centerVertical="true" android:layout_marginTop="12dp"
android:layout_marginLeft="12dp" android:layout_marginEnd="24dp"
android:layout_marginRight="12dp" android:text="@string/forgot_password_subtitle"
android:background="@drawable/secondcardview" app:layout_constraintEnd_toEndOf="parent"
android:orientation="vertical" app:layout_constraintStart_toStartOf="parent"
android:padding="12dp"> app:layout_constraintTop_toBottomOf="@+id/forgotPassword" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent" android:id="@+id/til_submission"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="6dp"> 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/forgotPassword_subtitle_tv">
<EditText <EditText
android:id="@+id/reset_pw" android:id="@+id/submission_et"
style="@style/edittexttheme"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:ems="10" android:hint="@string/prompt_email"
android:hint="Enter Emil Address"
android:inputType="textEmailAddress" android:inputType="textEmailAddress"
android:maxLines="1" /> android:maxLines="1"
android:selectAllOnFocus="true"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
</LinearLayout> <androidx.cardview.widget.CardView
android:id="@+id/submission_button"
<Button android:layout_width="match_parent"
android:id="@+id/reset_pw_sign_up"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_marginStart="24dp"
android:layout_alignParentRight="true" android:layout_marginTop="16dp"
android:layout_alignParentBottom="true" android:layout_marginEnd="24dp"
android:layout_margin="12dp" android:layout_marginBottom="64dp"
android:background="@drawable/cardviewoutline" android:backgroundTint="@color/colorPrimary"
android:text="Sign Up" android:enabled="false"
android:textColor="#91ddff" app:cardCornerRadius="8dp"
android:textStyle="bold" /> 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.9">
</RelativeLayout> <TextView
</FrameLayout> android:id="@+id/submission_button_label"
style="@style/button_inner_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/action_submit"
android:textColor="@android:color/white" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,149 +1,126 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
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" android:background="@android:color/white"
android:gravity="center_horizontal"
android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin"
android:background="@drawable/spash_drawable" tools:context=".ui.login.FullscreenActivity">
tools:context="com.appttude.h_mal.days_left.Login.FullscreenActivity">
<!-- Login progress --> <TextView
<RelativeLayout android:id="@+id/login_title_tv"
style="@style/title_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="96dp"
android:layout_marginEnd="24dp"
android:text="@string/login_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/login_subtitle_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
android:text="@string/login_subtitle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/login_title_tv" />
<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/login_subtitle_tv">
<EditText
android:id="@+id/submission_et"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:id="@+id/email_login_form">
<LinearLayout
android:id="@+id/fields_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:orientation="vertical">
<androidx.cardview.widget.CardView
style="@style/cardview_theme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
app:cardBackgroundColor="@color/two">
<AutoCompleteTextView
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="18dp"
android:layout_marginRight="18dp"
android:autofilledHighlight="@android:color/transparent"
android:ems="10"
android:hint="@string/prompt_email" android:hint="@string/prompt_email"
android:importantForAutofill="yes"
android:inputType="textEmailAddress" android:inputType="textEmailAddress"
android:maxLines="1" android:maxLines="1"
android:selectAllOnFocus="true" android:selectAllOnFocus="true"
android:singleLine="true" android:singleLine="true" />
android:textColorHighlight="@color/three" /> </com.google.android.material.textfield.TextInputLayout>
</androidx.cardview.widget.CardView> <com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_password"
<androidx.cardview.widget.CardView android:layout_width="0dp"
style="@style/cardview_theme"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:cardBackgroundColor="@color/two"> android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_submission">
<EditText <EditText
android:id="@+id/password" android:id="@+id/password"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginLeft="18dp"
android:layout_marginRight="18dp"
android:autofilledHighlight="@android:color/transparent"
android:ems="10"
android:hint="@string/prompt_password" android:hint="@string/prompt_password"
android:imeActionId="6"
android:imeActionLabel="@string/action_sign_in_short" android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionUnspecified" android:imeOptions="actionDone"
android:importantForAutofill="yes"
android:inputType="textPassword" android:inputType="textPassword"
android:maxLines="1" android:maxLines="1"
android:selectAllOnFocus="true" android:selectAllOnFocus="true"
android:singleLine="true" android:singleLine="true" />
android:textColorHighlight="@color/three" /> </com.google.android.material.textfield.TextInputLayout>
<!--</android.support.design.widget.TextInputLayout>--> <!--todo: reactivate forgot password-->
</androidx.cardview.widget.CardView> <TextView
android:id="@+id/forgotPassword"
<LinearLayout android:layout_width="wrap_content"
android:id="@+id/register"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:layout_marginRight="18dp" android:text="@string/forgot_password"
android:layout_marginLeft="18dp"> android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/submission_button" />
<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="16dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="64dp"
android:backgroundTint="@color/colorPrimary"
android:enabled="false"
app:cardCornerRadius="8dp"
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.9">
<TextView <TextView
android:id="@+id/forgot" android:id="@+id/submission_button_label"
android:layout_width="0dp" style="@style/button_inner_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_weight="1"
android:shadowColor="@color/five"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="1"
android:text="Forgot Password"
android:textColor="@color/one"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/register_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:paddingRight="2dp"
android:shadowColor="@color/five"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="1"
android:text="Sign up"
android:textColor="@color/one"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
<Button
android:id="@+id/email_sign_in_button"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:background="@drawable/cardviewoutline"
android:text="@string/action_sign_in_short" android:text="@string/action_sign_in_short"
android:textColor="@color/three" android:textColor="@android:color/white" />
android:textStyle="bold" /> </androidx.cardview.widget.CardView>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<ProgressBar
android:id="@+id/login_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginBottom="8dp"
android:visibility="gone" />
</RelativeLayout>

View File

@@ -0,0 +1,108 @@
<?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:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:background="@android:color/white"
tools:context=".ui.login.FullscreenActivity">
<ImageView
android:id="@+id/prova_logo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="48dp"
android:layout_marginEnd="24dp"
android:adjustViewBounds="true"
android:src="@drawable/farmicon_round"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent=".60" />
<TextView
android:id="@+id/prova_title_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
android:selectAllOnFocus="true"
android:text="@string/welcome_title"
style="@style/title_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/prova_logo" />
<TextView
android:id="@+id/prova_subtitle_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
android:selectAllOnFocus="true"
android:text="@string/welcome_subtitle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/prova_title_tv" />
<androidx.cardview.widget.CardView
android:id="@+id/sign_up"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
android:backgroundTint="#D5D5D5"
app:cardCornerRadius="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/prova_subtitle_tv">
<TextView
android:id="@+id/sign_up_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:gravity="center"
android:text="@string/register"
android:textColor="@android:color/black"
android:textSize="18sp"
android:textStyle="bold" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/submission_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:backgroundTint="@color/colorPrimary"
android:selectAllOnFocus="true"
app:cardCornerRadius="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sign_up">
<TextView
android:id="@+id/login_button_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:gravity="center"
android:text="@string/login"
android:textColor="@android:color/white"
android:textSize="18sp"
android:textStyle="bold" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,90 @@
<?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: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"
tools:context=".ui.login.FullscreenActivity">
<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_marginTop="96dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="Enter Your Nickname" />
<TextView
android:id="@+id/submission_subtitle_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
android:lines="3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/submission_title_tv"
android:text="Please enter your first name or the name you prefer to be called by." />
<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_subtitle_tv">
<EditText
android:id="@+id/submission_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/prompt_nickname"
android:inputType="textPersonName"
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_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="64dp"
android:backgroundTint="@color/colorPrimary"
android:enabled="false"
app:cardCornerRadius="8dp"
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.9">
<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/next"
android:textColor="@android:color/white"
tools:text="Next" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,24 +1,35 @@
<?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:background="@drawable/spash_drawable" android:background="@drawable/spash_drawable"
tools:context="com.appttude.h_mal.days_left.Login.FullscreenActivity"> tools:context=".ui.login.FullscreenActivity">
<ProgressBar <ProgressBar
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/pb" android:id="@+id/pb"
android:visibility="gone"/> android:elevation="0.2dp"
android:visibility="gone"
tools:visibility="visible"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<LinearLayout <LinearLayout
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"
android:padding="12dp" android:padding="12dp"
android:layout_centerInParent="true"> android:layout_centerInParent="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
style="@style/cardview_theme" style="@style/cardview_theme"
@@ -136,4 +147,4 @@
android:textColor="#91ddff" android:textColor="#91ddff"
android:textStyle="bold" /> android:textStyle="bold" />
</RelativeLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,90 @@
<?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: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"
tools:context=".ui.login.FullscreenActivity">
<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_marginTop="96dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="Enter Your Password" />
<TextView
android:id="@+id/submission_subtitle_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
android:lines="3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/submission_title_tv"
android:text="Please enter your password again. This is to confirm your passwords match." />
<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_subtitle_tv">
<EditText
android:id="@+id/submission_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/prompt_password"
android:inputType="textPassword"
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_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="64dp"
android:backgroundTint="@color/colorPrimary"
android:enabled="false"
app:cardCornerRadius="8dp"
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.9">
<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/next"
android:textColor="@android:color/white"
tools:text="Next" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,90 @@
<?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: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"
tools:context=".ui.login.FullscreenActivity">
<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_marginTop="96dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="Enter Your Password" />
<TextView
android:id="@+id/submission_subtitle_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
android:lines="3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/submission_title_tv"
android:text="Please enter your password/ This will be used for signing in" />
<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_subtitle_tv">
<EditText
android:id="@+id/submission_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/prompt_password"
android:inputType="textPassword"
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_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="64dp"
android:backgroundTint="@color/colorPrimary"
android:enabled="false"
app:cardCornerRadius="8dp"
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.9">
<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/next"
android:textColor="@android:color/white"
tools:text="Next" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,90 @@
<?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: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"
tools:context=".ui.login.FullscreenActivity">
<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_marginTop="96dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="Enter Your Email address" />
<TextView
android:id="@+id/submission_subtitle_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
android:lines="3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/submission_title_tv"
android:text="Please enter your email address. This will be used for signing in" />
<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_subtitle_tv">
<EditText
android:id="@+id/submission_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/prompt_email"
android:inputType="textEmailAddress"
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_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="64dp"
android:backgroundTint="@color/colorPrimary"
android:enabled="false"
app:cardCornerRadius="8dp"
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.9">
<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/next"
android:textColor="@android:color/white"
tools:text="Next" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,123 @@
<?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/auth_navigation"
app:startDestination="@id/loginHomeFragment">
<fragment
android:id="@+id/loginHomeFragment"
android:name="com.appttude.h_mal.days_left.ui.login.LoginHomeFragment"
android:label="LoginHomeFragment"
tools:layout="@layout/fragment_login_home">
<action
android:id="@+id/to_registrationNicknameFragment"
app:destination="@id/registrationNicknameFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_open_enter"
app:popExitAnim="@anim/fragment_open_exit"/>
<action
android:id="@+id/splash_to_loginFragment"
app:destination="@id/loginFragment"
app:launchSingleTop="true"
app:enterAnim="@anim/fragment_fade_enter"
app:exitAnim="@anim/fragment_fade_exit"
app:popEnterAnim="@anim/fragment_fade_enter"
app:popExitAnim="@anim/fragment_fade_exit"/>
</fragment>
<activity
android:id="@+id/mainActivity"
android:name="com.appttude.h_mal.days_left.ui.main.MainActivity"
android:label="activity_main"
tools:layout="@layout/activity_main" />
<fragment
android:id="@+id/loginFragment"
android:name="com.appttude.h_mal.days_left.ui.login.LoginFragment"
android:label="LoginFragment"
tools:layout="@layout/fragment_login">
<action
android:id="@+id/LoginTo_mainActivity"
app:destination="@id/mainActivity"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_open_enter"
app:popExitAnim="@anim/fragment_open_exit"/>
<action
android:id="@+id/action_loginFragment_to_forgotPassword"
app:destination="@id/forgotPassword"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_open_enter"
app:popExitAnim="@anim/fragment_open_exit"/>
</fragment>
<fragment
android:id="@+id/forgotPassword"
android:name="com.appttude.h_mal.days_left.ui.login.ForgotPassword"
android:label="ForgotPassword"
tools:layout="@layout/fragment_forgot_password"/>
<fragment
android:id="@+id/registrationNicknameFragment"
android:name="com.appttude.h_mal.days_left.ui.login.registration.RegistrationNicknameFragment"
android:label="RegistrationNicknameFragment"
tools:layout="@layout/fragment_nickname">
<action
android:id="@+id/to_registrationEmail"
app:destination="@id/registrationEmailFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_open_enter"
app:popExitAnim="@anim/fragment_open_exit"/>
</fragment>
<fragment
android:id="@+id/registrationEmailFragment"
android:name="com.appttude.h_mal.days_left.ui.login.registration.RegistrationEmailFragment"
android:label="RegistrationEmailFragment"
tools:layout="@layout/fragment_registration_two">
<action
android:id="@+id/to_registrationPasswordFragment"
app:destination="@id/registrationPasswordFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_open_enter"
app:popExitAnim="@anim/fragment_open_exit"/>
<argument
android:name="regOneArgs"
app:argType="com.appttude.h_mal.days_left.models.registration.RegistrationArgs" />
</fragment>
<fragment
android:id="@+id/registrationPasswordFragment"
android:name="com.appttude.h_mal.days_left.ui.login.registration.RegistrationPasswordFragment"
android:label="RegistrationPasswordFragment"
tools:layout="@layout/fragment_registration_password">
<action
android:id="@+id/to_registrationConfirmationFragment"
app:destination="@id/registrationConfirmationFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_open_enter"
app:popExitAnim="@anim/fragment_open_exit"/>
<argument
android:name="regTwoArgs"
app:argType="com.appttude.h_mal.days_left.models.registration.RegistrationArgs" />
</fragment>
<fragment
android:id="@+id/registrationConfirmationFragment"
android:name="com.appttude.h_mal.days_left.ui.login.registration.RegistrationConfirmationFragment"
android:label="RegistrationConfirmationFragment"
tools:layout="@layout/fragment_registration_four">
<action
android:id="@+id/registration_to_mainActivity"
app:destination="@id/mainActivity"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_open_enter"
app:popExitAnim="@anim/fragment_open_exit"/>
<argument
android:name="regThreeArgs"
app:argType="com.appttude.h_mal.days_left.models.registration.RegistrationArgs" />
</fragment>
</navigation>

View File

@@ -1,5 +1,5 @@
<resources> <resources>
<string name="app_name">Days_Left</string> <string name="app_name">Days Left</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_dashboard">List</string> <string name="title_dashboard">List</string>
<string name="title_notifications">Tools</string> <string name="title_notifications">Tools</string>
@@ -16,7 +16,7 @@
<string name="title_activity_login">Sign in</string> <string name="title_activity_login">Sign in</string>
<!-- Strings related to login --> <!-- Strings related to login -->
<string name="prompt_email">Email</string> <string name="prompt_email">Email</string>
<string name="prompt_password">Password (optional)</string> <string name="prompt_password">Password</string>
<string name="action_sign_in">Sign in or register</string> <string name="action_sign_in">Sign in or register</string>
<string name="action_sign_in_short">Sign in</string> <string name="action_sign_in_short">Sign in</string>
<string name="error_invalid_email">This email address is invalid</string> <string name="error_invalid_email">This email address is invalid</string>
@@ -39,6 +39,20 @@
<string name="empty_line_one">List is Empty</string> <string name="empty_line_one">List is Empty</string>
<string name="empty_line_two">Search for an Employer</string> <string name="empty_line_two">Search for an Employer</string>
<string name="submit">Submit</string> <string name="submit">Submit</string>
<string name="welcome_title">Welcome to Days Left</string>
<string name="welcome_subtitle">Use days left to track your rural work progress, track your work done and compile data needed for visa applications.</string>
<string name="register">Regiseter</string>
<string name="login">Login</string>
<string name="login_title">Login</string>
<string name="login_subtitle">Login to your account with your email address and password.</string>
<string name="forgot_password">Forgot Password</string>
<string name="forgot_password_subtitle">Enter your email address and receive a reset password email.</string>
<string name="action_submit">Submit</string>
<string name="prompt_nickname">Enter a nickname</string>
<string name="next">Next</string>
<string name="invalid_username">Not a valid username</string>
<string name="invalid_password">Password must contain 816 characters, including at least 1 upper case letter and at least 1 numerical digit.</string>
<string name="password_reset_success">Password reset successful</string>
<string-array name="work_type"> <string-array name="work_type">
<item>Select work type…</item> <item>Select work type…</item>

View File

@@ -63,4 +63,17 @@
</style> </style>
<style name="title_text" parent="TextAppearance.AppCompat">
<item name="android:textSize">32sp</item>
<item name="android:textStyle">bold</item>
</style>
<style name="button_inner_text" parent="TextAppearance.AppCompat">
<item name="android:gravity">center</item>
<item name="android:textSize">18sp</item>
<item name="android:textStyle">bold</item>
<item name="android:layout_margin">8dp</item>
</style>
</resources> </resources>

View File

@@ -12,7 +12,7 @@ buildscript {
classpath 'com.google.gms:google-services:4.2.0' classpath 'com.google.gms:google-services:4.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.0"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
} }