feat: Информация о пользователе + фиксы багов
This commit is contained in:
parent
eb4a59e4fe
commit
8cd87144b8
@ -39,15 +39,6 @@ class EmployeeInfoNetworkDataSource(
|
||||
HttpStatusCode.NotFound -> error(context.getString(R.string.not_found))
|
||||
HttpStatusCode.OK -> result.body()
|
||||
}
|
||||
if(result.status == HttpStatusCode.Unauthorized){
|
||||
error(context.getString(R.string.admin_unauthorized))
|
||||
}
|
||||
if (result.status != HttpStatusCode.OK) {
|
||||
println(result.status)
|
||||
error("Status ${result.status}")
|
||||
|
||||
}
|
||||
|
||||
println(result.bodyAsText())
|
||||
result.body()
|
||||
}
|
||||
|
@ -18,11 +18,11 @@ class ScannerStateNetworkDataSource(
|
||||
) {
|
||||
private val client = NetworkModule.httpClient
|
||||
private val userDataStoreManager = UserDataStoreManager.getInstance(context)
|
||||
suspend fun setScannerState(state: String, login: String):Result<Unit> = withContext(Dispatchers.IO){
|
||||
suspend fun setScannerState(login: String):Result<Unit> = withContext(Dispatchers.IO){
|
||||
runCatching {
|
||||
val username = userDataStoreManager.usernameFlow.first()
|
||||
val password = userDataStoreManager.passwordFlow.first()
|
||||
val result = client.patch("${Constants.SERVER_ADDRESS}/api/employee/$login/$state"){
|
||||
val result = client.patch("${Constants.SERVER_ADDRESS}/api/employee/$login/change_state"){
|
||||
headers{
|
||||
basicAuth(username, password)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import ru.myitschool.work.domain.scannerBlockState.ScannerStateRepo
|
||||
class ScannerStateRepoImpl(
|
||||
private val networkDataSource: ScannerStateNetworkDataSource
|
||||
) : ScannerStateRepo {
|
||||
override suspend fun changeState(state: String, login: String) : Result<Unit> {
|
||||
return networkDataSource.setScannerState(state, login)
|
||||
override suspend fun changeState(login: String) : Result<Unit> {
|
||||
return networkDataSource.setScannerState(login)
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
package ru.myitschool.work.domain.scannerBlockState
|
||||
|
||||
interface ScannerStateRepo {
|
||||
suspend fun changeState(state: String, login: String) : Result<Unit>
|
||||
suspend fun changeState(login: String) : Result<Unit>
|
||||
}
|
@ -3,5 +3,5 @@ package ru.myitschool.work.domain.scannerBlockState
|
||||
class SetScannerStateUseCase(
|
||||
private val repo: ScannerStateRepo
|
||||
) {
|
||||
suspend operator fun invoke(state: String, login: String) = repo.changeState(state, login)
|
||||
suspend operator fun invoke(login: String) = repo.changeState(login)
|
||||
}
|
@ -8,11 +8,15 @@ import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.squareup.picasso.Picasso
|
||||
import ru.myitschool.work.R
|
||||
import ru.myitschool.work.databinding.FragmentAdminBinding
|
||||
import ru.myitschool.work.entities.EmployeeEntity
|
||||
import ru.myitschool.work.ui.login.LoginViewModel
|
||||
import ru.myitschool.work.utils.buttonRecolor
|
||||
import ru.myitschool.work.utils.collectWithLifecycle
|
||||
|
||||
|
||||
class AdminFragment : Fragment(R.layout.fragment_admin) {
|
||||
private var _binding: FragmentAdminBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
@ -37,6 +41,7 @@ class AdminFragment : Fragment(R.layout.fragment_admin) {
|
||||
val isEnabled =
|
||||
search.length >= 3 && !search[0].isDigit() && search.matches(Regex("^[a-zA-Z0-9]*$"))
|
||||
binding.searchBtn.isEnabled = isEnabled
|
||||
@Suppress("DEPRECATION")
|
||||
if (isEnabled) {
|
||||
binding.searchBtn.setBackgroundColor(resources.getColor(R.color.accent_color))
|
||||
binding.searchBtn.imageTintList = ColorStateList.valueOf(
|
||||
@ -52,31 +57,63 @@ class AdminFragment : Fragment(R.layout.fragment_admin) {
|
||||
R.color.secondary_text_color
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
binding.search.addTextChangedListener(textWatcher)
|
||||
viewModel.infoState.collectWithLifecycle(this){ state ->
|
||||
when(state){
|
||||
is AdminViewModel.SearchState.Error -> {
|
||||
binding.error.visibility = View.VISIBLE
|
||||
binding.error.text = state.message
|
||||
binding.userInfo.visibility = View.GONE
|
||||
|
||||
}
|
||||
AdminViewModel.SearchState.Loading -> {
|
||||
binding.error.visibility = View.GONE
|
||||
binding
|
||||
binding.userInfo.visibility = View.GONE
|
||||
}
|
||||
is AdminViewModel.SearchState.Success -> {
|
||||
binding.error.visibility = View.GONE
|
||||
binding.userInfo.visibility = View.VISIBLE
|
||||
showUserData(state.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.blockBtn.setOnClickListener {
|
||||
viewModel.changeState(binding.search.text.toString())
|
||||
|
||||
}
|
||||
viewModel.blockState.collectWithLifecycle(this){ state ->
|
||||
when(state){
|
||||
is AdminViewModel.BlockState.Error -> {
|
||||
binding.error.visibility = View.VISIBLE
|
||||
binding.error.text = state.message
|
||||
}
|
||||
AdminViewModel.BlockState.Loading -> {
|
||||
binding.error.visibility = View.GONE
|
||||
binding.userInfo.visibility = View.GONE
|
||||
}
|
||||
AdminViewModel.BlockState.Success -> {
|
||||
binding.error.visibility = View.GONE
|
||||
binding.userInfo.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private fun showUserData(user: EmployeeEntity){
|
||||
binding.userName.text = user.name
|
||||
binding.position.text = user.position
|
||||
if(user.qrEnabled){
|
||||
binding.blockBtn.text = ContextCompat.getString(requireContext(), R.string.block_btn)
|
||||
buttonRecolor(requireContext(), binding.blockBtn, R.color.accent_color, R.color.white )
|
||||
}
|
||||
else{
|
||||
binding.blockBtn.text = ContextCompat.getString(requireContext(), R.string.unblock_btn)
|
||||
buttonRecolor(requireContext(), binding.blockBtn, R.color.bg_color, R.color.secondary_text_color )
|
||||
}
|
||||
Picasso.get().load(user.photoUrl).into(binding.avatar)
|
||||
}
|
||||
|
||||
}
|
@ -12,22 +12,34 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import ru.myitschool.work.data.profile.admin.EmployeeInfoNetworkDataSource
|
||||
import ru.myitschool.work.data.profile.admin.EmployeeInfoRepoImpl
|
||||
import ru.myitschool.work.data.scannerState.ScannerStateNetworkDataSource
|
||||
import ru.myitschool.work.data.scannerState.ScannerStateRepoImpl
|
||||
import ru.myitschool.work.domain.profile.admin.EmployeeInfoRepo
|
||||
import ru.myitschool.work.domain.profile.admin.GetEmployeeInfoUseCase
|
||||
import ru.myitschool.work.domain.scannerBlockState.SetScannerStateUseCase
|
||||
import ru.myitschool.work.entities.EmployeeEntity
|
||||
|
||||
class AdminViewModel(
|
||||
private val getInfoUseCase: GetEmployeeInfoUseCase,
|
||||
private val setScannerStateUseCase : SetScannerStateUseCase,
|
||||
application: Application
|
||||
) : AndroidViewModel(application) {
|
||||
private val _infoState = MutableStateFlow<SearchState>(SearchState.Loading)
|
||||
val infoState: StateFlow<SearchState> = _infoState.asStateFlow()
|
||||
|
||||
private val _blockState = MutableStateFlow<BlockState>(BlockState.Loading)
|
||||
val blockState: StateFlow<BlockState> = _blockState.asStateFlow()
|
||||
|
||||
sealed class SearchState {
|
||||
data object Loading : SearchState()
|
||||
data class Success(val data: EmployeeEntity) : SearchState()
|
||||
data class Error(val message: String?) : SearchState()
|
||||
}
|
||||
sealed class BlockState {
|
||||
data object Loading : BlockState()
|
||||
data object Success : BlockState()
|
||||
data class Error(val message: String?) : BlockState()
|
||||
}
|
||||
fun searchUser(login : String){
|
||||
_infoState.value = SearchState.Loading
|
||||
viewModelScope.launch {
|
||||
@ -41,6 +53,20 @@ class AdminViewModel(
|
||||
)
|
||||
}
|
||||
}
|
||||
fun changeState(login: String){
|
||||
viewModelScope.launch {
|
||||
_blockState.value = BlockState.Loading
|
||||
setScannerStateUseCase.invoke(login).fold(
|
||||
onSuccess = { _ ->
|
||||
_blockState.value = BlockState.Success
|
||||
},
|
||||
onFailure = { e ->
|
||||
_blockState.value = BlockState.Error(e.message)
|
||||
}
|
||||
)
|
||||
}
|
||||
searchUser(login)
|
||||
}
|
||||
companion object {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
|
||||
@ -50,10 +76,16 @@ class AdminViewModel(
|
||||
context = extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as Application
|
||||
)
|
||||
)
|
||||
val useCase = GetEmployeeInfoUseCase(infoRepoImpl)
|
||||
val setScannerStateRepoImpl = ScannerStateRepoImpl(
|
||||
networkDataSource = ScannerStateNetworkDataSource(
|
||||
context = extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as Application
|
||||
)
|
||||
)
|
||||
val getInfoUseCase = GetEmployeeInfoUseCase(infoRepoImpl)
|
||||
val setScannerStateUseCase = SetScannerStateUseCase(setScannerStateRepoImpl)
|
||||
|
||||
return AdminViewModel(
|
||||
useCase, extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as Application
|
||||
getInfoUseCase, setScannerStateUseCase, extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as Application
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
@ -39,9 +39,9 @@ class MainFragment : Fragment(R.layout.fragment_main) {
|
||||
|
||||
viewModel.getUserData()
|
||||
viewModel.getLastEntryDate()
|
||||
findNavController().navigate(R.id.admin)
|
||||
binding.logout.setOnClickListener { logout() }
|
||||
binding.scan.setOnClickListener { onScanClick() }
|
||||
binding.admin.setOnClickListener { findNavController().navigate(R.id.admin) }
|
||||
viewModel.userState.collectWhenStarted(this) { state ->
|
||||
when (state) {
|
||||
is UserState.Error -> {
|
||||
|
21
app/src/main/java/ru/myitschool/work/utils/ButtonRecolor.kt
Normal file
21
app/src/main/java/ru/myitschool/work/utils/ButtonRecolor.kt
Normal file
@ -0,0 +1,21 @@
|
||||
package ru.myitschool.work.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.widget.Button
|
||||
import androidx.core.content.ContextCompat
|
||||
import ru.myitschool.work.R
|
||||
|
||||
fun buttonRecolor(
|
||||
context: Context,
|
||||
btn: Button,
|
||||
bgColor: Int,
|
||||
textColor: Int
|
||||
) {
|
||||
btn.backgroundTintList = ColorStateList.valueOf(
|
||||
ContextCompat.getColor(
|
||||
context,
|
||||
bgColor
|
||||
))
|
||||
btn.setTextColor(context.getColor(textColor))
|
||||
}
|
@ -78,6 +78,7 @@
|
||||
app:layout_constraintVertical_bias="0.0">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/userInfo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
|
@ -5,7 +5,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/bg_color">
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline_left"
|
||||
android:layout_width="wrap_content"
|
||||
@ -18,7 +18,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_end="16dp"/>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linear"
|
||||
android:layout_width="0dp"
|
||||
@ -150,6 +150,12 @@
|
||||
app:layout_constraintLeft_toRightOf="@+id/guideline_left"
|
||||
app:layout_constraintRight_toLeftOf="@+id/guideline_right">
|
||||
|
||||
<Button
|
||||
android:id="@+id/admin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Admin" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/position"
|
||||
style="@style/font_medium"
|
||||
|
@ -20,4 +20,7 @@
|
||||
<string name="search_hint">Enter the employee\'s username</string>
|
||||
<string name="block_btn">Block</string>
|
||||
<string name="unblock_btn">Unblock</string>
|
||||
<string name="admin_unauthorized">Вы не авторизованы</string>
|
||||
<string name="admin_forbidden">Нет доступа</string>
|
||||
<string name="not_found">404\nEmployee not found</string>
|
||||
</resources>
|
@ -22,6 +22,9 @@
|
||||
<string name="search_hint">Введите логин сотрудника</string>
|
||||
<string name="block_btn">Заблокировать</string>
|
||||
<string name="unblock_btn">Разблокировать</string>
|
||||
<string name="admin_unauthorized">Вы не авторизованы</string>
|
||||
<string name="admin_forbidden">Нет доступа</string>
|
||||
<string name="not_found">404\nСотрудник не найден</string>
|
||||
<!-- TODO: Remove or change this placeholder text -->
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user