diff --git a/app/src/main/java/ru/myitschool/work/data/profile/admin/EmployeeInfoNetworkDataSource.kt b/app/src/main/java/ru/myitschool/work/data/profile/admin/EmployeeInfoNetworkDataSource.kt index 06e8821..5bcd299 100644 --- a/app/src/main/java/ru/myitschool/work/data/profile/admin/EmployeeInfoNetworkDataSource.kt +++ b/app/src/main/java/ru/myitschool/work/data/profile/admin/EmployeeInfoNetworkDataSource.kt @@ -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() } diff --git a/app/src/main/java/ru/myitschool/work/data/scannerState/ScannerStateNetworkDataSource.kt b/app/src/main/java/ru/myitschool/work/data/scannerState/ScannerStateNetworkDataSource.kt index 06edff0..aea40ff 100644 --- a/app/src/main/java/ru/myitschool/work/data/scannerState/ScannerStateNetworkDataSource.kt +++ b/app/src/main/java/ru/myitschool/work/data/scannerState/ScannerStateNetworkDataSource.kt @@ -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 = withContext(Dispatchers.IO){ + suspend fun setScannerState(login: String):Result = 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) } diff --git a/app/src/main/java/ru/myitschool/work/data/scannerState/ScannerStateRepoImpl.kt b/app/src/main/java/ru/myitschool/work/data/scannerState/ScannerStateRepoImpl.kt index c24b4fa..d82646e 100644 --- a/app/src/main/java/ru/myitschool/work/data/scannerState/ScannerStateRepoImpl.kt +++ b/app/src/main/java/ru/myitschool/work/data/scannerState/ScannerStateRepoImpl.kt @@ -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 { - return networkDataSource.setScannerState(state, login) + override suspend fun changeState(login: String) : Result { + return networkDataSource.setScannerState(login) } } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/domain/scannerBlockState/ScannerStateRepo.kt b/app/src/main/java/ru/myitschool/work/domain/scannerBlockState/ScannerStateRepo.kt index 8be93e8..7784401 100644 --- a/app/src/main/java/ru/myitschool/work/domain/scannerBlockState/ScannerStateRepo.kt +++ b/app/src/main/java/ru/myitschool/work/domain/scannerBlockState/ScannerStateRepo.kt @@ -1,5 +1,5 @@ package ru.myitschool.work.domain.scannerBlockState interface ScannerStateRepo { - suspend fun changeState(state: String, login: String) : Result + suspend fun changeState(login: String) : Result } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/domain/scannerBlockState/SetScannerStateUseCase.kt b/app/src/main/java/ru/myitschool/work/domain/scannerBlockState/SetScannerStateUseCase.kt index 24719f8..c13d2de 100644 --- a/app/src/main/java/ru/myitschool/work/domain/scannerBlockState/SetScannerStateUseCase.kt +++ b/app/src/main/java/ru/myitschool/work/domain/scannerBlockState/SetScannerStateUseCase.kt @@ -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) } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/admin/AdminFragment.kt b/app/src/main/java/ru/myitschool/work/ui/admin/AdminFragment.kt index 591b287..eb8e281 100644 --- a/app/src/main/java/ru/myitschool/work/ui/admin/AdminFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/admin/AdminFragment.kt @@ -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) } + } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/admin/AdminViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/admin/AdminViewModel.kt index c1ff377..c7c8019 100644 --- a/app/src/main/java/ru/myitschool/work/ui/admin/AdminViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/admin/AdminViewModel.kt @@ -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.Loading) val infoState: StateFlow = _infoState.asStateFlow() + private val _blockState = MutableStateFlow(BlockState.Loading) + val blockState: StateFlow = _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 } } diff --git a/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt b/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt index 48c376c..cdf4989 100644 --- a/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt @@ -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 -> { diff --git a/app/src/main/java/ru/myitschool/work/utils/ButtonRecolor.kt b/app/src/main/java/ru/myitschool/work/utils/ButtonRecolor.kt new file mode 100644 index 0000000..abd1b5e --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/utils/ButtonRecolor.kt @@ -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)) +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_admin.xml b/app/src/main/res/layout/fragment_admin.xml index 022ecb5..fc54d03 100644 --- a/app/src/main/res/layout/fragment_admin.xml +++ b/app/src/main/res/layout/fragment_admin.xml @@ -78,6 +78,7 @@ app:layout_constraintVertical_bias="0.0"> - + - + +