added admin panel, some fixes
This commit is contained in:
parent
9b70fd4dfd
commit
ac107e1635
@ -44,6 +44,12 @@ class UserServiceST(
|
|||||||
}
|
}
|
||||||
return userRepository.getInfo(tokenManager.authTokenPair!!.accessToken)
|
return userRepository.getInfo(tokenManager.authTokenPair!!.accessToken)
|
||||||
}
|
}
|
||||||
|
suspend fun getInfoByLogin(login: String): Result<UserDTO>{
|
||||||
|
if (!tokenManager.hasTokens()) {
|
||||||
|
throw RuntimeException("access token is null")
|
||||||
|
}
|
||||||
|
return userRepository.getInfoByLogin(tokenManager.authTokenPair!!.accessToken, login)
|
||||||
|
}
|
||||||
suspend fun openDoor(code: String): Result<Int> {
|
suspend fun openDoor(code: String): Result<Int> {
|
||||||
return userRepository.openDoor(tokenManager.authTokenPair!!.accessToken, code = code)
|
return userRepository.openDoor(tokenManager.authTokenPair!!.accessToken, code = code)
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,22 @@ class UserRepository(
|
|||||||
result.body()
|
result.body()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
suspend fun getInfoByLogin(token: String, login: String): Result<UserDTO> = withContext(Dispatchers.IO){
|
||||||
|
runCatching {
|
||||||
|
val encodedLogin = login.encodeURLPath()
|
||||||
|
val result = Network.client.get("$serverUrl/api/users/login/$encodedLogin") {
|
||||||
|
headers {
|
||||||
|
append(HttpHeaders.Authorization, "Bearer $token")
|
||||||
|
}
|
||||||
|
setBody("""{ "code": "$encodedLogin" }""")
|
||||||
|
}
|
||||||
|
if (result.status != HttpStatusCode.OK) {
|
||||||
|
error("Status ${result.status}: ${result.body<String>()}")
|
||||||
|
}
|
||||||
|
Log.d("UserRepository", result.bodyAsText())
|
||||||
|
result.body()
|
||||||
|
}
|
||||||
|
}
|
||||||
suspend fun openDoor(token: String, code: Long): Result<Unit> = withContext(Dispatchers.IO) {
|
suspend fun openDoor(token: String, code: Long): Result<Unit> = withContext(Dispatchers.IO) {
|
||||||
runCatching {
|
runCatching {
|
||||||
val result = Network.client.patch("$serverUrl/api/open") {
|
val result = Network.client.patch("$serverUrl/api/open") {
|
||||||
|
@ -23,4 +23,4 @@ data class UserDTO (
|
|||||||
|
|
||||||
@SerialName("lastVisit")
|
@SerialName("lastVisit")
|
||||||
val lastVisit: String,
|
val lastVisit: String,
|
||||||
)
|
) : java.io.Serializable
|
@ -1,5 +1,5 @@
|
|||||||
package com.displaynone.acss.config
|
package com.displaynone.acss.config
|
||||||
|
|
||||||
object Constants {
|
object Constants {
|
||||||
const val serverUrl = "http://192.168.1.107:8080"
|
const val serverUrl = "http://192.168.56.1:8086"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.displaynone.acss.ui.admin
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import com.displaynone.acss.R
|
||||||
|
import com.displaynone.acss.util.collectWithLifecycle
|
||||||
|
import com.displaynone.acss.util.navigateTo
|
||||||
|
import com.displaynone.acss.databinding.FragmentAdminBinding
|
||||||
|
import com.displaynone.acss.databinding.FragmentAuthBinding
|
||||||
|
|
||||||
|
class AdminFragment : Fragment(R.layout.fragment_admin) {
|
||||||
|
private var _binding: FragmentAdminBinding? = null
|
||||||
|
private val binding: FragmentAdminBinding get() = _binding!!
|
||||||
|
|
||||||
|
private val viewModel: AdminViewModel by viewModels()
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
_binding = FragmentAdminBinding.bind(view)
|
||||||
|
|
||||||
|
subscribeToState(view)
|
||||||
|
|
||||||
|
binding.buttonSearch.setOnClickListener{
|
||||||
|
onSearchButtonClicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onSearchButtonClicked() {
|
||||||
|
val login = binding.editTextTextEmailAddress.text.toString()
|
||||||
|
if (login.isEmpty()) return
|
||||||
|
|
||||||
|
viewModel.getDataByLogin(login)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun subscribeToState(view: View){
|
||||||
|
viewModel.state.collectWithLifecycle(this){ state ->
|
||||||
|
if (state is AdminViewModel.State.Show){
|
||||||
|
val userDto = state.item
|
||||||
|
val bundle = Bundle().apply{
|
||||||
|
putSerializable("user", userDto)
|
||||||
|
}
|
||||||
|
navigateTo(view, R.id.action_adminFragment_to_profileFragment, bundle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.displaynone.acss.ui.admin
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.displaynone.acss.components.auth.models.user.UserServiceST
|
||||||
|
import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO
|
||||||
|
import com.displaynone.acss.ui.profile.ProfileViewModel.State
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class AdminViewModel: ViewModel() {
|
||||||
|
val _state = MutableStateFlow<State>(State.Loading)
|
||||||
|
val state = _state.asStateFlow()
|
||||||
|
fun getDataByLogin(login: String){
|
||||||
|
viewModelScope.launch {
|
||||||
|
UserServiceST.getInstance().getInfoByLogin(login).fold(
|
||||||
|
onSuccess = { dto ->
|
||||||
|
_state.emit(State.Show(item = dto))
|
||||||
|
},
|
||||||
|
onFailure = { error ->
|
||||||
|
error.message?.let { error(it) }
|
||||||
|
Log.e("AdminViewModel", error.message.toString()) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface State {
|
||||||
|
data class Show(
|
||||||
|
val item: UserDTO
|
||||||
|
): State
|
||||||
|
data object Loading : State
|
||||||
|
}
|
||||||
|
}
|
@ -22,14 +22,17 @@ class AuthFragment: Fragment(R.layout.fragment_auth) {
|
|||||||
|
|
||||||
private val viewModel: AuthViewModel by viewModels()
|
private val viewModel: AuthViewModel by viewModels()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
_binding = FragmentAuthBinding.bind(view)
|
_binding = FragmentAuthBinding.bind(view)
|
||||||
setupLoginButton()
|
setupLoginButton()
|
||||||
|
|
||||||
viewModel.action.collectWithLifecycle(this) { action ->
|
viewModel.action.collectWithLifecycle(this) { action ->
|
||||||
when (action) {
|
if (action is Action.GotoProfile) {
|
||||||
Action.GotoProfile -> navigateTo(view, R.id.action_authFragment_to_profileFragment)
|
blockLoginButton() // FIXME() При двойном нажатии вылетает с ошибкой
|
||||||
|
navigateTo(view, R.id.action_authFragment_to_profileFragment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
viewModel.errorState.collectWithLifecycle(this) { errorMessage ->
|
viewModel.errorState.collectWithLifecycle(this) { errorMessage ->
|
||||||
@ -43,7 +46,9 @@ class AuthFragment: Fragment(R.layout.fragment_auth) {
|
|||||||
onLoginButtonClicked(view)
|
onLoginButtonClicked(view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private fun blockLoginButton() {
|
||||||
|
binding.next.isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupLoginButton() {
|
private fun setupLoginButton() {
|
||||||
binding.login.addTextChangedListener(object : TextWatcher {
|
binding.login.addTextChangedListener(object : TextWatcher {
|
||||||
@ -79,7 +84,6 @@ class AuthFragment: Fragment(R.layout.fragment_auth) {
|
|||||||
private fun onLoginButtonClicked(view: View) {
|
private fun onLoginButtonClicked(view: View) {
|
||||||
val login = binding.login.text.toString()
|
val login = binding.login.text.toString()
|
||||||
if (login.isEmpty()) return
|
if (login.isEmpty()) return
|
||||||
|
|
||||||
viewModel.login(login)
|
viewModel.login(login)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,11 +37,23 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) {
|
|||||||
binding.scan.setOnClickListener{
|
binding.scan.setOnClickListener{
|
||||||
viewModel.openScan()
|
viewModel.openScan()
|
||||||
}
|
}
|
||||||
|
val user = getUserDto()
|
||||||
|
if (user == null) {
|
||||||
|
refreshData()
|
||||||
|
waitForQRScanResult()
|
||||||
|
} else{
|
||||||
|
showData(user) // TODO() не показывать кнопки
|
||||||
|
}
|
||||||
subscribe()
|
subscribe()
|
||||||
refreshData()
|
|
||||||
waitForQRScanResult()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showData(userDTO: UserDTO){
|
||||||
|
binding.fio.text = userDTO.name
|
||||||
|
binding.position.text = userDTO.position
|
||||||
|
binding.lastEntry.text = userDTO.lastVisit
|
||||||
|
setAvatar(userDTO.photo)
|
||||||
|
}
|
||||||
private fun refreshData() {
|
private fun refreshData() {
|
||||||
Log.d("ProfileFragment", "Refreshed")
|
Log.d("ProfileFragment", "Refreshed")
|
||||||
viewModel.getInfo()
|
viewModel.getInfo()
|
||||||
@ -53,10 +65,13 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) {
|
|||||||
view?.let { navigateTo(it, R.id.action_profileFragment_to_authFragment) } ?: throw IllegalStateException("View is null")
|
view?.let { navigateTo(it, R.id.action_profileFragment_to_authFragment) } ?: throw IllegalStateException("View is null")
|
||||||
}
|
}
|
||||||
if (action is Action.GoToScan) {
|
if (action is Action.GoToScan) {
|
||||||
view?.let { navigateTo(it, R.id.action_profileFragment_to_qrScanFragment) }?: throw IllegalStateException("View is null")
|
view?.let { navigateTo(it, R.id.action_profileFragment_to_adminFragment) }?: throw IllegalStateException("View is null")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private fun getUserDto(): UserDTO? {
|
||||||
|
return arguments?.getSerializable("user") as? UserDTO
|
||||||
|
}
|
||||||
private fun waitForQRScanResult() {
|
private fun waitForQRScanResult() {
|
||||||
|
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(
|
requireActivity().onBackPressedDispatcher.addCallback(
|
||||||
@ -89,10 +104,7 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) {
|
|||||||
viewModel.state.collectWithLifecycle(this) { state ->
|
viewModel.state.collectWithLifecycle(this) { state ->
|
||||||
if (state is ProfileViewModel.State.Show) {
|
if (state is ProfileViewModel.State.Show) {
|
||||||
val userDto: UserDTO = state.item
|
val userDto: UserDTO = state.item
|
||||||
binding.fio.text = userDto.name
|
showData(userDto)
|
||||||
binding.position.text = userDto.position
|
|
||||||
binding.lastEntry.text = userDto.lastVisit
|
|
||||||
setAvatar(userDto.photo)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
<action
|
<action
|
||||||
android:id="@+id/action_profileFragment_to_qrResultFragment"
|
android:id="@+id/action_profileFragment_to_qrResultFragment"
|
||||||
app:destination="@id/qrResultFragment" />
|
app:destination="@id/qrResultFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_profileFragment_to_adminFragment"
|
||||||
|
app:destination="@id/adminFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/authFragment"
|
android:id="@+id/authFragment"
|
||||||
@ -38,4 +41,12 @@
|
|||||||
android:id="@+id/action_qrResultFragment_to_profileFragment"
|
android:id="@+id/action_qrResultFragment_to_profileFragment"
|
||||||
app:destination="@id/profileFragment" />
|
app:destination="@id/profileFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/adminFragment"
|
||||||
|
android:name="com.displaynone.acss.ui.admin.AdminFragment"
|
||||||
|
android:label="AdminFragment" >
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_adminFragment_to_profileFragment"
|
||||||
|
app:destination="@id/profileFragment" />
|
||||||
|
</fragment>
|
||||||
</navigation>
|
</navigation>
|
Loading…
x
Reference in New Issue
Block a user