diff --git a/data/src/main/java/com/nto/data/utils/RetrofitApi.kt b/data/src/main/java/com/nto/data/utils/RetrofitApi.kt index 40b8878..a07f64a 100644 --- a/data/src/main/java/com/nto/data/utils/RetrofitApi.kt +++ b/data/src/main/java/com/nto/data/utils/RetrofitApi.kt @@ -11,7 +11,7 @@ import retrofit2.http.PUT import retrofit2.http.Query interface RetrofitApi { - @GET("employee/admin/auth") + @GET("employee/auth") fun auth(@Header("Authorization") token: String): Call @GET("employee/info") diff --git a/domain/src/main/java/com/nto/domain/usecase/LoginUseCase.kt b/domain/src/main/java/com/nto/domain/usecase/LoginUseCase.kt index 37d4244..41aa8de 100644 --- a/domain/src/main/java/com/nto/domain/usecase/LoginUseCase.kt +++ b/domain/src/main/java/com/nto/domain/usecase/LoginUseCase.kt @@ -12,5 +12,4 @@ class LoginUseCase @Inject constructor(private val domainRepositoryImpl: DomainR suspend fun auth(email: String, password: String): LoginResult { return domainRepositoryImpl.auth(email, password) } - } \ No newline at end of file diff --git a/domain/src/main/java/com/nto/domain/usecase/SplashScreenUseCase.kt b/domain/src/main/java/com/nto/domain/usecase/SplashScreenUseCase.kt new file mode 100644 index 0000000..3a6c0f1 --- /dev/null +++ b/domain/src/main/java/com/nto/domain/usecase/SplashScreenUseCase.kt @@ -0,0 +1,10 @@ +package com.nto.domain.usecase + +import com.nto.domain.repository.DomainRepositoryImpl +import javax.inject.Inject + +class SplashScreenUseCase @Inject constructor(private val domainRepositoryImpl: DomainRepositoryImpl) { + suspend fun getToken(): String? { + return domainRepositoryImpl.getToken() + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/nto/presentation/MainActivity.kt b/presentation/src/main/java/com/nto/presentation/MainActivity.kt index 7c14f27..064bce3 100644 --- a/presentation/src/main/java/com/nto/presentation/MainActivity.kt +++ b/presentation/src/main/java/com/nto/presentation/MainActivity.kt @@ -1,42 +1,48 @@ package com.nto.presentation -import android.app.Activity -import android.os.Build import android.os.Bundle -import android.view.WindowInsets import androidx.activity.ComponentActivity -import androidx.activity.compose.LocalActivity import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge +import androidx.activity.viewModels import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Scaffold +import androidx.compose.runtime.collectAsState import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalContext +import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.compose.rememberNavController import com.nto.presentation.composable.Navigation +import com.nto.presentation.screens.splashScreen.SplashScreenViewModel import com.nto.presentation.theme.NTOTheme +import com.nto.presentation.theme.TextColor import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class MainActivity : ComponentActivity() { + val viewmodel by viewModels() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContent { - NTOTheme { - //XML SUCKS! We use Jetpack Compose btw :> - this.window.statusBarColor = NTOTheme.colors.primaryText.toArgb() - Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> - val navController = rememberNavController() - Navigation( - navController = navController, - modifier = Modifier - .padding(innerPadding) - .fillMaxSize() - ) + this.window.statusBarColor = TextColor.toArgb() + viewmodel.checkLogin().apply { + setContent { + NTOTheme { + //XML SUCKS! We use Jetpack Compose btw :> + val state = viewmodel.state.collectAsState().value + + Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> + val navController = rememberNavController() + Navigation( + navController = navController, + modifier = Modifier + .padding(innerPadding) + .fillMaxSize(), + skipAuth = state.skipAuth + ) + } } } } diff --git a/presentation/src/main/java/com/nto/presentation/composable/Navigation.kt b/presentation/src/main/java/com/nto/presentation/composable/Navigation.kt index 1bbb8f3..dcdf45f 100644 --- a/presentation/src/main/java/com/nto/presentation/composable/Navigation.kt +++ b/presentation/src/main/java/com/nto/presentation/composable/Navigation.kt @@ -11,11 +11,11 @@ import com.nto.presentation.screens.profileScreen.ProfileScreen import com.nto.presentation.screens.scanResult.ScanResultScreen @Composable -fun Navigation(navController: NavHostController, modifier: Modifier = Modifier) { +fun Navigation(navController: NavHostController, skipAuth: Boolean, modifier: Modifier = Modifier) { NavHost( navController = navController, modifier = modifier, - startDestination = Destinations.Login + startDestination = if (skipAuth) Destinations.Profile else Destinations.Login ) { composable { LoginScreen(navController) diff --git a/presentation/src/main/java/com/nto/presentation/screens/loginScreen/LoginScreen.kt b/presentation/src/main/java/com/nto/presentation/screens/loginScreen/LoginScreen.kt index 6c1c2c6..044100a 100644 --- a/presentation/src/main/java/com/nto/presentation/screens/loginScreen/LoginScreen.kt +++ b/presentation/src/main/java/com/nto/presentation/screens/loginScreen/LoginScreen.kt @@ -20,7 +20,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight diff --git a/presentation/src/main/java/com/nto/presentation/screens/loginScreen/LoginViewModel.kt b/presentation/src/main/java/com/nto/presentation/screens/loginScreen/LoginViewModel.kt index 5c279d3..ef586f5 100644 --- a/presentation/src/main/java/com/nto/presentation/screens/loginScreen/LoginViewModel.kt +++ b/presentation/src/main/java/com/nto/presentation/screens/loginScreen/LoginViewModel.kt @@ -18,7 +18,9 @@ import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class LoginViewModel @Inject constructor(private val useCase: LoginUseCase, @ApplicationContext private val context: Context) : ViewModel() { +class LoginViewModel @Inject constructor( + private val useCase: LoginUseCase, @ApplicationContext private val context: Context +) : ViewModel() { private val _state = MutableStateFlow(LoginScreenState()) val state: StateFlow @@ -52,7 +54,7 @@ class LoginViewModel @Inject constructor(private val useCase: LoginUseCase, @App if (result.successful) { Dispatchers.Main { navController.navigate(Destinations.Profile) { - popUpTo() { + popUpTo { inclusive = true } } diff --git a/presentation/src/main/java/com/nto/presentation/screens/profileScreen/ProfileState.kt b/presentation/src/main/java/com/nto/presentation/screens/profileScreen/ProfileState.kt index 9fe77c9..f050f30 100644 --- a/presentation/src/main/java/com/nto/presentation/screens/profileScreen/ProfileState.kt +++ b/presentation/src/main/java/com/nto/presentation/screens/profileScreen/ProfileState.kt @@ -16,18 +16,22 @@ data class ProfileState( var job: String = "", var isUnauthorized: Boolean = false, val visits: List = listOf() -){ - fun deserialize(o: UserDTO, context: Context){ +) { + fun deserialize(o: UserDTO, context: Context) { val dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") this.firstName = o.firstName this.secondName = o.secondName this.thirdName = o.thirdName - this.lastOpen = o.lastVisit.format(dateFormat) + this.lastOpen = try { + o.lastVisit.format(dateFormat) + } catch (e: NullPointerException) { + "Exception!" + } this.job = translatePosition(o.position, context) this.isUnauthorized = o.isUnauthorized } - private fun translatePosition(position: Position, context:Context): String { + 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) diff --git a/presentation/src/main/java/com/nto/presentation/screens/splashScreen/SplashScreenState.kt b/presentation/src/main/java/com/nto/presentation/screens/splashScreen/SplashScreenState.kt new file mode 100644 index 0000000..068e4a5 --- /dev/null +++ b/presentation/src/main/java/com/nto/presentation/screens/splashScreen/SplashScreenState.kt @@ -0,0 +1,5 @@ +package com.nto.presentation.screens.splashScreen + +data class SplashScreenState( + val skipAuth: Boolean = false +) diff --git a/presentation/src/main/java/com/nto/presentation/screens/splashScreen/SplashScreenViewModel.kt b/presentation/src/main/java/com/nto/presentation/screens/splashScreen/SplashScreenViewModel.kt new file mode 100644 index 0000000..59d2b31 --- /dev/null +++ b/presentation/src/main/java/com/nto/presentation/screens/splashScreen/SplashScreenViewModel.kt @@ -0,0 +1,31 @@ +package com.nto.presentation.screens.splashScreen + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.nto.domain.usecase.SplashScreenUseCase +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class SplashScreenViewModel @Inject constructor(private val useCase: SplashScreenUseCase) : ViewModel(){ + private val _state = MutableStateFlow( + SplashScreenState() + ) + + val state: StateFlow + get() = _state.asStateFlow() + + fun checkLogin(){ + viewModelScope.launch(Dispatchers.IO) { + val token = useCase.getToken() + if (!token.isNullOrBlank()){ + _state.tryEmit(_state.value.copy(skipAuth = true)) + } + } + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/nto/presentation/theme/Color.kt b/presentation/src/main/java/com/nto/presentation/theme/Color.kt index 42b52aa..b3b06a7 100644 --- a/presentation/src/main/java/com/nto/presentation/theme/Color.kt +++ b/presentation/src/main/java/com/nto/presentation/theme/Color.kt @@ -12,6 +12,7 @@ val Green = Color(0xFF738D73) val GreenDisabled = Color(0xFFCAD5CA) val Error = Color(0xFFD28989) val Warning = Color(0xFFCFC37F) +val TextColor = Color(0xFF211A1D) @Immutable data class AppColors( @@ -51,7 +52,7 @@ val extendedColor = AppColors( secondaryBackground = Color.Black, inputFieldBackground = BoxGray, disabledText = TextGray, - primaryText = Color.Black, + primaryText = TextColor, secondaryText = Color.White, button = Green, buttonDisabled = GreenDisabled,