Экран ввода данных сотрудника

This commit is contained in:
v228a 2025-02-20 14:16:36 +03:00
parent 052a7716a5
commit 48110115dc
5 changed files with 145 additions and 22 deletions

View File

@ -1,6 +1,8 @@
package ru.myitschool.work.ui.searchuser package ru.myitschool.work.ui.searchuser
import android.os.Bundle import android.os.Bundle
import ru.myitschool.work.utils.collectWhenStarted
import ru.myitschool.work.utils.visibleOrGone
import android.view.View import android.view.View
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
@ -9,7 +11,6 @@ import dagger.hilt.android.AndroidEntryPoint
import ru.myitschool.work.R import ru.myitschool.work.R
import ru.myitschool.work.databinding.FragmentSearchUserBinding import ru.myitschool.work.databinding.FragmentSearchUserBinding
import ru.myitschool.work.ui.profile.ProfileDestination import ru.myitschool.work.ui.profile.ProfileDestination
import ru.myitschool.work.utils.collectWhenStarted
@AndroidEntryPoint @AndroidEntryPoint
@ -18,7 +19,6 @@ class SearchUserFragment : Fragment(R.layout.fragment_search_user) {
private var _binding: FragmentSearchUserBinding? = null private var _binding: FragmentSearchUserBinding? = null
private val binding: FragmentSearchUserBinding get() = _binding!! private val binding: FragmentSearchUserBinding get() = _binding!!
private val viewModel: SearchUserViewModel by viewModels() private val viewModel: SearchUserViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -27,11 +27,18 @@ class SearchUserFragment : Fragment(R.layout.fragment_search_user) {
initCallback() initCallback()
subscribe() subscribe()
// Set the initial state to not show the loading state
} }
private fun initCallback() { private fun initCallback() {
binding.floatingActionButton2.setOnClickListener { viewModel.closeSearchUser() } binding.floatingActionButton2.setOnClickListener { viewModel.closeSearchUser() }
binding.login.setOnClickListener {
// Clear error text before starting search
binding.error?.text = ""
// Set loading state before calling search method
viewModel.setLoadingState()
viewModel.searchUser(binding.username.text.toString())
}
} }
private fun subscribe() { private fun subscribe() {
@ -44,9 +51,30 @@ class SearchUserFragment : Fragment(R.layout.fragment_search_user) {
} }
} }
} }
viewModel.state.collectWhenStarted(this) { state ->
//binding.loading?.visibleOrGone(state is SearchUserViewModel.State.Loading)
// Manage visibility of progress bar and error text
binding.error?.visibleOrGone(state is SearchUserViewModel.State.Error)
//binding.loading?.visibility = View.GONE
when (state) {
//TODO ПОчинить прогресс бар
is SearchUserViewModel.State.Error -> {
// Set error text
binding.error?.text = state.errorText.localizedMessage
// binding.loading?.visibility = View.GONE
}
is SearchUserViewModel.State.Loading -> {
// Additional logic can be added here if needed
// binding.loading?.visibility = View.VISIBLE
}
}
}
} }
override fun onDestroyView() {
super.onDestroyView()
_binding = null // Release binding to avoid memory leaks
} }
}

View File

@ -1,12 +1,17 @@
package ru.myitschool.work.ui.searchuser package ru.myitschool.work.ui.searchuser
import android.content.Context import android.content.Context
import android.util.Log
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import ru.myitschool.work.R
import ru.myitschool.work.utils.MutablePublishFlow import ru.myitschool.work.utils.MutablePublishFlow
import javax.inject.Inject import javax.inject.Inject
@ -17,12 +22,62 @@ class SearchUserViewModel @Inject constructor(
private val _action = MutablePublishFlow<Action>() private val _action = MutablePublishFlow<Action>()
val action = _action.asSharedFlow() val action = _action.asSharedFlow()
fun closeSearchUser(){ private val _state = MutableStateFlow<State>(
initialState
)
val state = _state.asStateFlow()
fun closeSearchUser() {
viewModelScope.launch { viewModelScope.launch {
_action.emit(Action.OpenProfile) _action.emit(Action.OpenProfile)
} }
} }
fun setLoadingState() {
viewModelScope.launch {
_state.update { State.Loading }
}
}
fun searchUser(userName: String) {
viewModelScope.launch {
setLoadingState()
// Simulating delay for data retrieval
kotlinx.coroutines.delay(1000) // Delay for 1 second
// Mock user check
val existingUsers = listOf("user1", "user2", "user3") // Mock users
val userExists = existingUsers.contains(userName)
if (userExists) {
// If user exists, log their name
Log.d("SearchUser ViewModel", "User found: $userName")
// Here you can update the state if needed
} else {
// If user does not exist, update state with error
val errorText = context.resources.getString(R.string.login_error)
_state.update {
State.Error(
errorText = Throwable("User not found: $errorText")
)
}
}
}
}
sealed interface Action { sealed interface Action {
data object OpenProfile: Action data object OpenProfile : Action
}
sealed interface State {
data object Loading : State
data class Error(
val errorText: Throwable,
) : State
}
companion object {
val initialState = State.Loading
} }
} }

View File

@ -3,6 +3,19 @@
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"> xmlns:app="http://schemas.android.com/apk/res-auto">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:progressTint="@color/AccentBlue"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View File

@ -113,6 +113,7 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:visibility="gone" android:visibility="gone"
style="@style/Theme.UiTemplate.TextH4" style="@style/Theme.UiTemplate.TextH4"
android:textColor="@color/ErrorRed"
android:layout_gravity="center" android:layout_gravity="center"
tools:text="Something wrong. Try again" /> tools:text="Something wrong. Try again" />
</LinearLayout> </LinearLayout>

View File

@ -3,11 +3,25 @@
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"> xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- <ProgressBar-->
<!-- android:id="@+id/loading"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:visibility="gone"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent" />-->
<LinearLayout <LinearLayout
android:id="@+id/dashboard"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp" android:padding="16dp"
android:orientation="vertical"> android:visibility="visible">
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton2" android:id="@+id/floatingActionButton2"
style="@style/Theme.UiTemplate.FAB.Gray" style="@style/Theme.UiTemplate.FAB.Gray"
@ -17,42 +31,54 @@
android:src="@drawable/ic_back" android:src="@drawable/ic_back"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/text_login" android:id="@+id/text_login"
android:padding="35dp"
style="@style/Theme.UiTemplate.TextH1" style="@style/Theme.UiTemplate.TextH1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_marginBottom="10dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:gravity="center"
android:padding="35dp"
android:text="@string/admin_main" /> android:text="@string/admin_main" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
style="@style/Theme.UiTemplate.Input"
android:id="@+id/input_username" android:id="@+id/input_username"
android:layout_marginTop="45dp" style="@style/Theme.UiTemplate.Input"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="58dp"
android:layout_marginTop="45dp"
app:errorEnabled="false"
app:layout_constraintWidth_max="400dp" app:layout_constraintWidth_max="400dp"
app:layout_constraintWidth_percent="0.8" app:layout_constraintWidth_percent="0.8">
android:layout_height="58dp">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/username" android:id="@+id/username"
style="@style/Theme.UiTemplate.Input.Text" style="@style/Theme.UiTemplate.Input.Text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="60dp"
android:hint="@string/admin_input_hint"
android:inputType="text" android:inputType="text"
android:maxLines="1" android:maxLines="1"></com.google.android.material.textfield.TextInputEditText>
android:hint="@string/admin_input_hint">
</com.google.android.material.textfield.TextInputEditText>
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<Button <Button
android:id="@+id/login" android:id="@+id/login"
style="@style/Theme.UiTemplate.Button"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
style="@style/Theme.UiTemplate.Button"
android:layout_marginTop="58dp"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="58dp"
android:text="@string/admin_button" /> android:text="@string/admin_button" />
<TextView
android:id="@+id/error"
style="@style/Theme.UiTemplate.TextH4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textColor="@color/ErrorRed"
android:visibility="gone" />
</LinearLayout> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>