Half-implement user retrieving logic
This commit is contained in:
parent
5c3e7bcdee
commit
ddbb5fdf8a
6
data/src/main/java/com/nto/data/models/QRDTO.kt
Normal file
6
data/src/main/java/com/nto/data/models/QRDTO.kt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package com.nto.data.models
|
||||||
|
|
||||||
|
data class QRDTO(
|
||||||
|
val id: Long = Long.MAX_VALUE,
|
||||||
|
val name: String = ""
|
||||||
|
)
|
18
data/src/main/java/com/nto/data/models/UserDTO.kt
Normal file
18
data/src/main/java/com/nto/data/models/UserDTO.kt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package com.nto.data.models
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
enum class Position {
|
||||||
|
DEVELOPER, DESIGNER, TESTER, ANALYST, ADMINISTRATOR
|
||||||
|
}
|
||||||
|
|
||||||
|
data class UserDTO(
|
||||||
|
val firstName: String = "",
|
||||||
|
val secondName: String = "",
|
||||||
|
val thirdName: String = "",
|
||||||
|
val position: Position = Position.DEVELOPER,
|
||||||
|
val lastVisit: LocalDateTime = LocalDateTime.now(),
|
||||||
|
val isError: Boolean = false,
|
||||||
|
val isUnauthorized: Boolean = false,
|
||||||
|
val localizedName: String = ""
|
||||||
|
)
|
@ -1,8 +1,16 @@
|
|||||||
package com.nto.data.models.cards
|
package com.nto.data.models.cards
|
||||||
|
|
||||||
|
import com.nto.data.models.QRDTO
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
enum class VisitType {
|
||||||
|
PHONE_ENTRY, CARD_ENTRY
|
||||||
|
}
|
||||||
|
|
||||||
data class VisitCardDTO(
|
data class VisitCardDTO(
|
||||||
val name: String = "",
|
val name: String = "",
|
||||||
val id: String = "",
|
val id: Long = Long.MAX_VALUE,
|
||||||
val dateString: String = "",
|
val dateString: LocalDateTime = LocalDateTime.now(),
|
||||||
val isCode: Boolean = false
|
val visitType: VisitType = VisitType.CARD_ENTRY,
|
||||||
|
val qrCode: QRDTO = QRDTO()
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package com.nto.data.repository
|
package com.nto.data.repository
|
||||||
|
|
||||||
import com.nto.data.models.LoginResult
|
import com.nto.data.models.LoginResult
|
||||||
|
import com.nto.data.models.UserDTO
|
||||||
|
|
||||||
interface DataRepository {
|
interface DataRepository {
|
||||||
suspend fun auth(login: String, password: String): LoginResult
|
suspend fun auth(login: String, password: String): LoginResult
|
||||||
suspend fun saveToken(token: String)
|
suspend fun saveToken(token: String)
|
||||||
suspend fun getToken(): String
|
suspend fun getToken(): String
|
||||||
suspend fun getInfo()
|
suspend fun getInfo(): UserDTO
|
||||||
}
|
}
|
@ -3,6 +3,7 @@ package com.nto.data.repository
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Context.MODE_PRIVATE
|
import android.content.Context.MODE_PRIVATE
|
||||||
import com.nto.data.models.LoginResult
|
import com.nto.data.models.LoginResult
|
||||||
|
import com.nto.data.models.UserDTO
|
||||||
import com.nto.data.utils.Provider
|
import com.nto.data.utils.Provider
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import okhttp3.Credentials
|
import okhttp3.Credentials
|
||||||
@ -27,8 +28,10 @@ class DataRepositoryImpl @Inject constructor(@ApplicationContext private val con
|
|||||||
return context.getSharedPreferences("auth", MODE_PRIVATE).getString("token", "")!!
|
return context.getSharedPreferences("auth", MODE_PRIVATE).getString("token", "")!!
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getInfo(){
|
override suspend fun getInfo(): UserDTO {
|
||||||
|
val result = Provider.provideRetrofit().getInfo(getToken()).execute()
|
||||||
|
return if (result.isSuccessful) result.body()!!
|
||||||
|
else UserDTO(isError = true, isUnauthorized = result.code() == 403)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,11 +1,15 @@
|
|||||||
package com.nto.data.utils
|
package com.nto.data.utils
|
||||||
|
|
||||||
|
import com.nto.data.models.UserDTO
|
||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
import retrofit2.http.Header
|
import retrofit2.http.Header
|
||||||
|
|
||||||
interface RetrofitApi {
|
interface RetrofitApi {
|
||||||
@GET("auth")
|
@GET("employee/auth")
|
||||||
fun auth(@Header("Authorization") token: String): Call<ResponseBody>
|
fun auth(@Header("Authorization") token: String): Call<ResponseBody>
|
||||||
|
|
||||||
|
@GET("employee/info")
|
||||||
|
fun getInfo(@Header("Authorization") token: String): Call<UserDTO>
|
||||||
}
|
}
|
@ -1,10 +1,11 @@
|
|||||||
package com.nto.domain.repository
|
package com.nto.domain.repository
|
||||||
|
|
||||||
import com.nto.data.models.LoginResult
|
import com.nto.data.models.LoginResult
|
||||||
|
import com.nto.data.models.UserDTO
|
||||||
|
|
||||||
interface DomainRepository {
|
interface DomainRepository {
|
||||||
suspend fun auth(email: String, password: String): LoginResult
|
suspend fun auth(email: String, password: String): LoginResult
|
||||||
suspend fun saveToken(token: String)
|
suspend fun saveToken(token: String)
|
||||||
suspend fun getToken(): String
|
suspend fun getToken(): String
|
||||||
suspend fun getInfo()
|
suspend fun getInfo(): UserDTO
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package com.nto.domain.repository
|
package com.nto.domain.repository
|
||||||
|
|
||||||
import com.nto.data.models.LoginResult
|
import com.nto.data.models.LoginResult
|
||||||
|
import com.nto.data.models.UserDTO
|
||||||
import com.nto.data.repository.DataRepositoryImpl
|
import com.nto.data.repository.DataRepositoryImpl
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -26,7 +27,7 @@ class DomainRepositoryImpl @Inject constructor(private val dataRepositoryImpl: D
|
|||||||
return dataRepositoryImpl.getToken()
|
return dataRepositoryImpl.getToken()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getInfo(){
|
override suspend fun getInfo(): UserDTO{
|
||||||
val result = dataRepositoryImpl.getInfo()
|
return dataRepositoryImpl.getInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,10 +1,11 @@
|
|||||||
package com.nto.domain.usecase
|
package com.nto.domain.usecase
|
||||||
|
|
||||||
|
import com.nto.data.models.UserDTO
|
||||||
import com.nto.domain.repository.DomainRepositoryImpl
|
import com.nto.domain.repository.DomainRepositoryImpl
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ProfileUseCase @Inject constructor(private val domainRepositoryImpl: DomainRepositoryImpl) {
|
class ProfileUseCase @Inject constructor(private val domainRepositoryImpl: DomainRepositoryImpl) {
|
||||||
suspend fun getInfo(){
|
suspend fun getInfo(): UserDTO{
|
||||||
domainRepositoryImpl.getInfo()
|
return domainRepositoryImpl.getInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -22,6 +22,7 @@ import androidx.compose.material3.Icon
|
|||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@ -35,6 +36,7 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.nto.data.utils.Destinations
|
||||||
import com.nto.presentation.R
|
import com.nto.presentation.R
|
||||||
import com.nto.presentation.composable.DecoratedButton
|
import com.nto.presentation.composable.DecoratedButton
|
||||||
import com.nto.presentation.composable.cards.VisitCard
|
import com.nto.presentation.composable.cards.VisitCard
|
||||||
@ -48,6 +50,11 @@ fun ProfileScreen(
|
|||||||
viewModel: ProfileViewModel = hiltViewModel<ProfileViewModel>(),
|
viewModel: ProfileViewModel = hiltViewModel<ProfileViewModel>(),
|
||||||
) {
|
) {
|
||||||
val state = viewModel.state.collectAsState().value
|
val state = viewModel.state.collectAsState().value
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
if (state.isUnauthorized) {
|
||||||
|
//navController.navigate(Destinations.Login)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier.background(NTOTheme.colors.primaryBackground)
|
modifier = modifier.background(NTOTheme.colors.primaryBackground)
|
||||||
@ -184,7 +191,7 @@ fun ProfileScreen(
|
|||||||
horizontalArrangement = Arrangement.SpaceBetween
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
stringResource(R.string.lablel_last_visit),
|
stringResource(R.string.label_last_visit),
|
||||||
style = NTOTheme.typography.placeholder,
|
style = NTOTheme.typography.placeholder,
|
||||||
fontSize = 12.sp
|
fontSize = 12.sp
|
||||||
)
|
)
|
||||||
@ -194,7 +201,7 @@ fun ProfileScreen(
|
|||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(20.dp))
|
Spacer(modifier = Modifier.height(20.dp))
|
||||||
Text(
|
Text(
|
||||||
stringResource(R.string.lablel_visits),
|
stringResource(R.string.label_visits),
|
||||||
style = NTOTheme.typography.displaySmall,
|
style = NTOTheme.typography.displaySmall,
|
||||||
fontWeight = FontWeight.Bold
|
fontWeight = FontWeight.Bold
|
||||||
)
|
)
|
||||||
@ -207,7 +214,7 @@ fun ProfileScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DecoratedButton(
|
DecoratedButton(
|
||||||
stringResource(R.string.lablel_scan),
|
stringResource(R.string.label_scan),
|
||||||
false,
|
false,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(10.dp)
|
.padding(10.dp)
|
||||||
|
@ -1,12 +1,37 @@
|
|||||||
package com.nto.presentation.screens.profileScreen
|
package com.nto.presentation.screens.profileScreen
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.nto.data.models.Position
|
||||||
|
import com.nto.data.models.UserDTO
|
||||||
import com.nto.data.models.cards.VisitCardDTO
|
import com.nto.data.models.cards.VisitCardDTO
|
||||||
|
import com.nto.presentation.R
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
data class ProfileState(
|
data class ProfileState(
|
||||||
val firstName: String = "",
|
var firstName: String = "",
|
||||||
val secondName: String = "",
|
var secondName: String = "",
|
||||||
val thirdName: String = "",
|
var thirdName: String = "",
|
||||||
val lastOpen: String = "",
|
var lastOpen: String = "",
|
||||||
val job: String = "",
|
var job: String = "",
|
||||||
|
var isUnauthorized: Boolean = false,
|
||||||
val visits: List<VisitCardDTO> = listOf()
|
val visits: List<VisitCardDTO> = listOf()
|
||||||
)
|
){
|
||||||
|
fun deserialize(o: UserDTO, context: Context){
|
||||||
|
this.firstName = o.firstName
|
||||||
|
this.secondName = o.secondName
|
||||||
|
this.thirdName = o.thirdName
|
||||||
|
this.lastOpen = o.lastVisit.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
|
||||||
|
this.job = translatePosition(o.position, context)
|
||||||
|
this.isUnauthorized = o.isUnauthorized
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translatePosition(position: Position, context:Context): String {
|
||||||
|
return when (position) {
|
||||||
|
Position.TESTER -> context.getString(R.string.label_tester)
|
||||||
|
Position.DEVELOPER -> context.getString(R.string.label_developer)
|
||||||
|
Position.DESIGNER -> context.getString(R.string.label_designer)
|
||||||
|
Position.ANALYST -> context.getString(R.string.label_analyst)
|
||||||
|
Position.ADMINISTRATOR -> context.getString(R.string.label_administrator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
package com.nto.presentation.screens.profileScreen
|
package com.nto.presentation.screens.profileScreen
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import com.nto.data.models.Position
|
||||||
import com.nto.data.utils.Destinations
|
import com.nto.data.utils.Destinations
|
||||||
import com.nto.domain.usecase.ProfileUseCase
|
import com.nto.domain.usecase.ProfileUseCase
|
||||||
|
import com.nto.presentation.R
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
@ -14,15 +18,19 @@ import kotlinx.coroutines.launch
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class ProfileViewModel @Inject constructor(private val useCase: ProfileUseCase) : ViewModel() {
|
class ProfileViewModel @Inject constructor(
|
||||||
|
private val useCase: ProfileUseCase, @ApplicationContext private val context: Context
|
||||||
|
) : ViewModel() {
|
||||||
private val _state = MutableStateFlow(ProfileState())
|
private val _state = MutableStateFlow(ProfileState())
|
||||||
|
|
||||||
val state: StateFlow<ProfileState>
|
val state: StateFlow<ProfileState>
|
||||||
get() = _state.asStateFlow()
|
get() = _state.asStateFlow()
|
||||||
|
|
||||||
fun updateInfo(){
|
fun updateInfo() {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
val result = useCase.getInfo()
|
val result = useCase.getInfo()
|
||||||
|
if (result.isError) return@launch
|
||||||
|
_state.tryEmit(ProfileState().apply { deserialize(result, context) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +51,6 @@ class ProfileViewModel @Inject constructor(private val useCase: ProfileUseCase)
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
updateInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,7 +10,12 @@
|
|||||||
<string name="title_profile">Профиль</string>
|
<string name="title_profile">Профиль</string>
|
||||||
<string name="label_qr_login">Вход по коду</string>
|
<string name="label_qr_login">Вход по коду</string>
|
||||||
<string name="label_card_login">Вход по карте</string>
|
<string name="label_card_login">Вход по карте</string>
|
||||||
<string name="lablel_last_visit">Последний вход:</string>
|
<string name="label_last_visit">Последний вход:</string>
|
||||||
<string name="lablel_visits">Посещения</string>
|
<string name="label_visits">Посещения</string>
|
||||||
<string name="lablel_scan">Сканировать код</string>
|
<string name="label_scan">Сканировать код</string>
|
||||||
|
<string name="label_tester">Тестировщик</string>
|
||||||
|
<string name="label_developer">Разработчик</string>
|
||||||
|
<string name="label_designer">Дизайнер</string>
|
||||||
|
<string name="label_analyst">Аналитик</string>
|
||||||
|
<string name="label_administrator">Администратор</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user