init
This commit is contained in:
parent
26e0b74bf3
commit
5c6f4c7815
@ -42,6 +42,11 @@ android {
|
||||
dependencies {
|
||||
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation("androidx.datastore:datastore-preferences:1.1.3")
|
||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
implementation("com.squareup.retrofit2:retrofit:2.11.0")
|
||||
implementation("com.squareup.retrofit2:converter-kotlinx-serialization:2.11.0")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0")
|
||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(platform(libs.androidx.compose.bom))
|
||||
@ -49,7 +54,6 @@ dependencies {
|
||||
implementation(libs.androidx.ui.graphics)
|
||||
implementation(libs.androidx.ui.tooling.preview)
|
||||
implementation(libs.androidx.material3)
|
||||
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
@ -57,12 +61,37 @@ dependencies {
|
||||
androidTestImplementation(libs.androidx.ui.test.junit4)
|
||||
debugImplementation(libs.androidx.ui.tooling)
|
||||
debugImplementation(libs.androidx.ui.test.manifest)
|
||||
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
|
||||
implementation("androidx.navigation:navigation-compose:2.8.9")
|
||||
|
||||
|
||||
implementation("androidx.datastore:datastore-preferences:1.1.3")
|
||||
|
||||
implementation("androidx.navigation:navigation-compose:2.8.9")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
|
||||
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
|
||||
implementation("com.squareup.retrofit2:retrofit:2.11.0")
|
||||
implementation("com.squareup.retrofit2:converter-gson:2.11.0")
|
||||
implementation("androidx.datastore:datastore-preferences:1.0.0")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0")
|
||||
implementation("androidx.navigation:navigation-compose:2.7.0")
|
||||
implementation("com.squareup.retrofit2:converter-kotlinx-serialization:2.11.0")
|
||||
// https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
|
||||
implementation("com.squareup.okhttp3:okhttp:4.7.2")
|
||||
|
||||
|
||||
implementation("io.insert-koin:koin-compose:4.1.0-Beta5")
|
||||
implementation("io.insert-koin:koin-compose-viewmodel:4.1.0-Beta5")
|
||||
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(platform(libs.androidx.compose.bom))
|
||||
implementation(libs.androidx.ui)
|
||||
implementation(libs.androidx.ui.graphics)
|
||||
implementation(libs.androidx.ui.tooling.preview)
|
||||
implementation(libs.androidx.material3)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||
androidTestImplementation(libs.androidx.ui.test.junit4)
|
||||
debugImplementation(libs.androidx.ui.tooling)
|
||||
debugImplementation(libs.androidx.ui.test.manifest)
|
||||
}
|
@ -1,19 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.ShoesappTest"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:name=".ui.MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.ShoesappTest">
|
||||
|
@ -1,19 +0,0 @@
|
||||
package com.example.shoesapptest
|
||||
|
||||
import com.example.shoesapptest.data.model.RegistrationRequest
|
||||
import com.example.shoesapptest.data.model.TokenResponse
|
||||
import com.example.shoesapptest.data.remote.AuthRemoteSource
|
||||
import com.example.shoesapptest.data.remote.retrofit.Auth
|
||||
import com.example.shoesapptest.data.remote.retrofit.RetrofitClient
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class AuthRemoteSourceImpl :AuthRemoteSource {
|
||||
private val api: Auth = RetrofitClient.retrofit
|
||||
|
||||
override suspend fun registration(registrationRequest: RegistrationRequest): TokenResponse {
|
||||
return withContext(Dispatchers.IO) {
|
||||
api.registration(registrationRequest)
|
||||
}
|
||||
}
|
||||
}
|
@ -4,61 +4,59 @@ import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.example.shoesapp.ui.screen.SigninScreen
|
||||
import com.example.shoesapp.ui.theme.MatuleTheme
|
||||
import com.example.shoesapptest.AuthRemoteSourceImpl
|
||||
import com.example.shoesapptest.RegistrationViewModelFactory
|
||||
import com.example.shoesapptest.data.local.datastore.LocalDataStore
|
||||
import com.example.shoesapptest.data.repository.AuthRepositoryImpl
|
||||
import com.example.shoesapptest.screen.RegistrationScreen
|
||||
import com.example.shoesapptest.screen.TestScreen
|
||||
import com.example.shoesapptest.screen.registrationscreen.RegistrationViewModel
|
||||
import com.example.shoesapptest.Screen
|
||||
import com.example.shoesapptest.data.local.DataStore
|
||||
import com.example.shoesapptest.data.remote.RetrofitClient
|
||||
|
||||
import com.example.shoesapptest.data.AuthRepository
|
||||
import com.example.shoesapptest.domain.usecase.AuthUseCase
|
||||
import com.example.shoesapptest.screen.ForgotPasswordScreen
|
||||
import com.example.shoesapptest.screen.regscreen.RegistrationScreen
|
||||
|
||||
import com.example.shoesapptest.ui.screen.registrationscreen.Registration
|
||||
import com.example.shoesapptest.ui.screen.registrationscreen.RegistrationViewModel
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
private lateinit var authLocalStore: LocalDataStore
|
||||
private lateinit var authRemoteSource: AuthRemoteSourceImpl
|
||||
private lateinit var authRepository: AuthRepositoryImpl
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
|
||||
// Инициализация зависимостей
|
||||
authLocalStore = LocalDataStore(applicationContext)
|
||||
authRemoteSource = AuthRemoteSourceImpl()
|
||||
authRepository = AuthRepositoryImpl(authLocalStore, authRemoteSource)
|
||||
|
||||
val registrationViewModel: RegistrationViewModel by viewModel()
|
||||
setContent {
|
||||
MatuleTheme {
|
||||
val navController = rememberNavController()
|
||||
MatuleTheme {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = "register"
|
||||
startDestination = "signin"
|
||||
) {
|
||||
composable("register") {
|
||||
// Создание и передача ViewModel
|
||||
val registrationViewModel: RegistrationViewModel = ViewModelProvider(
|
||||
this@MainActivity,
|
||||
RegistrationViewModelFactory(authRepository)
|
||||
).get(RegistrationViewModel::class.java)
|
||||
|
||||
RegistrationScreen(
|
||||
navController = navController,
|
||||
registrationViewModel = registrationViewModel
|
||||
composable(Screen.SignIn.route) {
|
||||
SigninScreen(
|
||||
onNavigationToRegScreen = {
|
||||
navController.navigate("registration")
|
||||
},
|
||||
navController = navController
|
||||
)
|
||||
}
|
||||
|
||||
composable("test") {
|
||||
TestScreen()
|
||||
composable(Screen.ForgotPass.route) {
|
||||
ForgotPasswordScreen(onNavigateToSignInScreen = {
|
||||
navController.navigate("signin")
|
||||
})
|
||||
}
|
||||
composable(Screen.Registration.route) {
|
||||
RegistrationScreen(
|
||||
onNavigationToSigninScreen = {
|
||||
navController.popBackStack()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
package com.example.shoesapptest
|
||||
|
||||
import android.app.Application
|
||||
import com.example.shoesapptest.di.appModules
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.core.context.startKoin
|
||||
|
||||
class MainApplication: Application() {
|
||||
override fun onCreate(){
|
||||
super.onCreate()
|
||||
startKoin{
|
||||
androidContext(applicationContext)
|
||||
modules(appModules)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.example.shoesapptest
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.example.shoesapptest.data.repository.AuthRepository
|
||||
import com.example.shoesapptest.screen.registrationscreen.RegistrationViewModel
|
||||
|
||||
class RegistrationViewModelFactory(
|
||||
private val authRepository: AuthRepository
|
||||
) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
if (modelClass.isAssignableFrom(RegistrationViewModel::class.java)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return RegistrationViewModel(authRepository) as T
|
||||
}
|
||||
throw IllegalArgumentException("Unknown ViewModel class")
|
||||
}
|
||||
}
|
7
app/src/main/java/com/example/shoesapptest/Screen.kt
Normal file
7
app/src/main/java/com/example/shoesapptest/Screen.kt
Normal file
@ -0,0 +1,7 @@
|
||||
package com.example.shoesapptest
|
||||
|
||||
sealed class Screen (val route: String) {
|
||||
object SignIn : Screen("signin")
|
||||
object ForgotPass : Screen("forgotpass")
|
||||
object Registration : Screen("registration")
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.example.shoesapptest.data
|
||||
|
||||
import com.example.shoesapptest.data.remote.auth.AuthApi
|
||||
import com.example.shoesapptest.data.remote.dto.request.RegistrationRequest
|
||||
import com.example.shoesapptest.data.remote.dto.response.RegistrationResponse
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
class AuthRepository(private val api: AuthApi) {
|
||||
suspend fun registration(registrationRequest: RegistrationRequest): RegistrationResponse {
|
||||
delay(3000)
|
||||
return api.registration(registrationRequest)
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.example.shoesapptest.data.local
|
||||
|
||||
import com.example.shoesapptest.data.model.SaveTokenRequest
|
||||
import com.example.shoesapptest.data.model.TokenResponse
|
||||
|
||||
interface AuthLocalStore {
|
||||
suspend fun getToken(): TokenResponse
|
||||
suspend fun setToken(saveTokenRequest: SaveTokenRequest): Boolean
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.example.shoesapptest.data.local
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
|
||||
class DataStore(private val context: Context) {
|
||||
val TOKEN_KEY = stringPreferencesKey("token_key")
|
||||
val tokenFlow : Flow<String> = context.dataStore.data.map { pref ->
|
||||
pref[TOKEN_KEY] ?: ""
|
||||
}
|
||||
suspend fun setToken(token: String){
|
||||
context.dataStore.edit { pref ->
|
||||
pref[TOKEN_KEY] = token
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package com.example.shoesapptest.data.local.datastore
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import com.example.shoesapptest.data.local.AuthLocalStore
|
||||
import com.example.shoesapptest.data.model.SaveTokenRequest
|
||||
import com.example.shoesapptest.data.model.TokenResponse
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
|
||||
private val Context.dataStore by preferencesDataStore(name="auth")
|
||||
|
||||
class LocalDataStore(context: Context): AuthLocalStore {
|
||||
private val dataStore = context.dataStore
|
||||
|
||||
override suspend fun getToken(): TokenResponse {
|
||||
val token = dataStore.data.map { preferences ->
|
||||
preferences[stringPreferencesKey("token")] ?: ""
|
||||
}.first()
|
||||
return TokenResponse("token")
|
||||
}
|
||||
|
||||
override suspend fun setToken(saveTokenRequest: SaveTokenRequest): Boolean {
|
||||
dataStore.edit { prefences -> prefences[stringPreferencesKey("token")] = saveTokenRequest.tokenAuthentication }
|
||||
return true
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package com.example.shoesapptest.data.model
|
||||
|
||||
data class RegistrationRequest(
|
||||
val userName: String,
|
||||
val email: String,
|
||||
val password: String
|
||||
)
|
@ -1,5 +0,0 @@
|
||||
package com.example.shoesapptest.data.model
|
||||
|
||||
data class SaveTokenRequest(
|
||||
val tokenAuthentication: String
|
||||
)
|
@ -1,5 +0,0 @@
|
||||
package com.example.shoesapptest.data.model
|
||||
|
||||
data class TokenResponse(
|
||||
val tokenAuthentication: String
|
||||
)
|
@ -1,8 +0,0 @@
|
||||
package com.example.shoesapptest.data.remote
|
||||
|
||||
import com.example.shoesapptest.data.model.RegistrationRequest
|
||||
import com.example.shoesapptest.data.model.TokenResponse
|
||||
|
||||
interface AuthRemoteSource {
|
||||
suspend fun registration(registrationRequest: RegistrationRequest):TokenResponse
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.example.shoesapptest.data.remote
|
||||
|
||||
sealed class NetworkResponse {
|
||||
data class Success<T>(val data: T): NetworkResponse()
|
||||
data object Loading:NetworkResponse()
|
||||
data class Error(val errorMessage: String): NetworkResponse()
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.example.shoesapptest.data.remote
|
||||
|
||||
import com.example.shoesapptest.data.remote.auth.AuthApi
|
||||
import com.example.shoesapptest.data.remote.auth.AuthRemoteSource
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.kotlinx.serialization.asConverterFactory
|
||||
|
||||
|
||||
object RetrofitClient {
|
||||
private const val URL = "http://26.197.138.194:8080"
|
||||
private val retrofit = Retrofit.Builder()
|
||||
.baseUrl(URL)
|
||||
.addConverterFactory(
|
||||
Json.asConverterFactory(
|
||||
"application/json; charset=UTF8".toMediaType()))
|
||||
.build()
|
||||
val auth by lazy {
|
||||
retrofit.create(AuthApi::class.java)
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.example.shoesapptest.data.remote.auth
|
||||
|
||||
import com.example.shoesapptest.data.remote.dto.request.RegistrationRequest
|
||||
import com.example.shoesapptest.data.remote.dto.response.RegistrationResponse
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.POST
|
||||
|
||||
interface AuthApi {
|
||||
@POST("/regitstration")
|
||||
suspend fun registration(@Body registrationRequest: RegistrationRequest): RegistrationResponse
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.example.shoesapptest.data.remote.auth
|
||||
|
||||
import com.example.shoesapptest.data.remote.dto.request.RegistrationRequest
|
||||
import com.example.shoesapptest.data.remote.dto.response.RegistrationResponse
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.POST
|
||||
|
||||
interface AuthRemoteSource {
|
||||
@POST("/registration")
|
||||
suspend fun registration(@Body registrationRequest: RegistrationRequest): RegistrationResponse
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.example.shoesapptest.data.remote.dto.request
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class RegistrationRequest(
|
||||
val userName: String,
|
||||
val email: String,
|
||||
val password: String
|
||||
)
|
@ -0,0 +1,9 @@
|
||||
package com.example.shoesapptest.data.remote.dto.response
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class RegistrationResponse (
|
||||
val first: String,
|
||||
val second: String
|
||||
)
|
@ -1,12 +0,0 @@
|
||||
package com.example.shoesapptest.data.remote.retrofit
|
||||
|
||||
import com.example.shoesapptest.data.model.RegistrationRequest
|
||||
import com.example.shoesapptest.data.model.TokenResponse
|
||||
import com.example.shoesapptest.data.remote.AuthRemoteSource
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.POST
|
||||
|
||||
interface Auth:AuthRemoteSource {
|
||||
@POST("/registration")
|
||||
override suspend fun registration(@Body registrationRequest: RegistrationRequest): TokenResponse
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package com.example.shoesapptest.data.remote.retrofit
|
||||
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
|
||||
private const val URL = "http://172.18.112.1:8080"
|
||||
object RetrofitClient {
|
||||
private val retrofitBuilder = Retrofit.Builder()
|
||||
.baseUrl(URL)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build()
|
||||
val retrofit by lazy {
|
||||
retrofitBuilder.create(Auth::class.java)
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.example.shoesapptest.data.repository
|
||||
|
||||
import com.example.shoesapptest.data.model.RegistrationRequest
|
||||
import com.example.shoesapptest.data.model.TokenResponse
|
||||
|
||||
|
||||
interface AuthRepository {
|
||||
suspend fun registration(registrationRequest: RegistrationRequest): TokenResponse
|
||||
suspend fun login()
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package com.example.shoesapptest.data.repository
|
||||
|
||||
import com.example.shoesapptest.data.local.AuthLocalStore
|
||||
import com.example.shoesapptest.data.model.RegistrationRequest
|
||||
import com.example.shoesapptest.data.model.SaveTokenRequest
|
||||
import com.example.shoesapptest.data.model.TokenResponse
|
||||
import com.example.shoesapptest.data.remote.AuthRemoteSource
|
||||
|
||||
class AuthRepositoryImpl(
|
||||
private val authLocalStore: AuthLocalStore,
|
||||
private val authRemoteSource: AuthRemoteSource
|
||||
):AuthRepository {
|
||||
|
||||
override suspend fun registration(registrationRequest: RegistrationRequest): TokenResponse {
|
||||
val tokenResponse = authRemoteSource.registration(registrationRequest)
|
||||
authLocalStore.setToken(SaveTokenRequest(tokenResponse.tokenAuthentication))
|
||||
return tokenResponse
|
||||
}
|
||||
|
||||
override suspend fun login() {
|
||||
}
|
||||
|
||||
}
|
18
app/src/main/java/com/example/shoesapptest/di/appModules.kt
Normal file
18
app/src/main/java/com/example/shoesapptest/di/appModules.kt
Normal file
@ -0,0 +1,18 @@
|
||||
package com.example.shoesapptest.di
|
||||
|
||||
import com.example.shoesapptest.data.AuthRepository
|
||||
import com.example.shoesapptest.data.local.DataStore
|
||||
import com.example.shoesapptest.data.remote.RetrofitClient
|
||||
import com.example.shoesapptest.domain.usecase.AuthUseCase
|
||||
import com.example.shoesapptest.screen.regscreen.RegistrationScreen
|
||||
import com.example.shoesapptest.ui.screen.registrationscreen.RegistrationViewModel
|
||||
import org.koin.core.module.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val appModules = module {
|
||||
single { DataStore(get()) }
|
||||
single { RetrofitClient.auth }
|
||||
single<AuthRepository> { AuthRepository(get()) }
|
||||
single { AuthUseCase(get(),get()) }
|
||||
viewModel { RegistrationViewModel(get())}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.example.shoesapptest.domain.usecase
|
||||
|
||||
import com.example.shoesapptest.data.AuthRepository
|
||||
import com.example.shoesapptest.data.local.DataStore
|
||||
import com.example.shoesapptest.data.remote.NetworkResponse
|
||||
import com.example.shoesapptest.data.remote.dto.request.RegistrationRequest
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
||||
class AuthUseCase (private val localStorage: DataStore,
|
||||
private val authRepository: AuthRepository) {
|
||||
val token: Flow<String> = localStorage.tokenFlow
|
||||
suspend fun registration(registrationRequest: RegistrationRequest): Flow<NetworkResponse> = flow{
|
||||
try{
|
||||
emit(NetworkResponse.Loading)
|
||||
val result = authRepository.registration(registrationRequest)
|
||||
localStorage.setToken(result.second)
|
||||
emit(NetworkResponse.Success(result))
|
||||
}
|
||||
catch (e:Exception){
|
||||
e.message?.let{
|
||||
emit(NetworkResponse.Error(it))
|
||||
return@flow
|
||||
}
|
||||
emit(NetworkResponse.Error("Unknown Error"))
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.example.shoesapptest.screen
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
@Composable
|
||||
fun TestScreen() {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(text = "Добро пожаловать!")
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package com.example.shoesapptest.screen.registrationscreen
|
||||
|
||||
import android.provider.ContactsContract.CommonDataKinds.Email
|
||||
import com.example.shoesapptest.screen.forgotscreen.ChangePass
|
||||
import java.lang.Error
|
||||
|
||||
data class Registration(
|
||||
var email: String = "",
|
||||
var password: String = "",
|
||||
var name: String = "",
|
||||
var isVisiblePassword: Boolean = false,
|
||||
var errorMessage: String? = null
|
||||
)
|
@ -1,197 +0,0 @@
|
||||
package com.example.shoesapptest.screen
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.ClickableText
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonColors
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.shoesapptest.R
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.navigation.NavController
|
||||
import com.example.shoesapp.ui.theme.MatuleTheme
|
||||
import com.example.shoesapptest.screen.forgotscreen.component.TitleWithSubtitleText
|
||||
import com.example.shoesapptest.screen.registrationscreen.RegistrationViewModel
|
||||
import com.example.shoesapptest.screen.registrationscreen.component.RegistrationBtn
|
||||
import com.example.shoesapptest.screen.registrationscreen.component.RegistrationTextField
|
||||
|
||||
@Composable
|
||||
fun RegistrationScreen(
|
||||
navController: NavController,
|
||||
registrationViewModel: RegistrationViewModel
|
||||
){
|
||||
Scaffold(
|
||||
topBar = {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(top = 35.dp)
|
||||
.fillMaxWidth()
|
||||
.height(40.dp)
|
||||
){
|
||||
IconButton(onClick={}) {
|
||||
Icon(painter = painterResource(R.drawable.back_arrow),
|
||||
contentDescription = null)
|
||||
}
|
||||
}
|
||||
},
|
||||
bottomBar = {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.padding(bottom = 50.dp)
|
||||
.fillMaxWidth()
|
||||
.height(40.dp)
|
||||
) {
|
||||
Text(
|
||||
text= stringResource(R.string.sign_in_on_reg),
|
||||
style=MatuleTheme.typography.bodyRegular16.copy(MatuleTheme.colors.text),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
) { paddingValues ->
|
||||
RegistrationScreen(
|
||||
paddingValues=paddingValues,
|
||||
registrationViewModel=registrationViewModel,
|
||||
onRegistrationSuccess = {navController.navigate("test")},
|
||||
onRegistrationError = {errorMessage -> }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RegistrationScreen(paddingValues: PaddingValues,
|
||||
registrationViewModel: RegistrationViewModel,
|
||||
onRegistrationSuccess: () -> Unit,
|
||||
onRegistrationError: (String) -> Unit){
|
||||
val register = registrationViewModel.registration
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(20.dp)
|
||||
) {
|
||||
TitleWithSubtitleText(
|
||||
title = "Регистрация",
|
||||
subTitle = "Заполните Свои данные или продолжите через социальные медиа"
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
RegistrationTextField(
|
||||
value = register.value.name,
|
||||
onChangeValue = { registrationViewModel.setUserName(it) },
|
||||
isError = false,
|
||||
supportingText = { Text(text = stringResource(R.string.wrong_name)) },
|
||||
placeholder = { Text(text = stringResource(R.string.template_name)) },
|
||||
label = { Text(text = stringResource(R.string.name)) }
|
||||
)
|
||||
RegistrationTextField(
|
||||
value = register.value.email,
|
||||
onChangeValue = { registrationViewModel.setEmail(it) },
|
||||
isError = registrationViewModel.emailHasError.value,
|
||||
supportingText = { Text(text = stringResource(R.string.wrong_email)) },
|
||||
placeholder = { Text(text = stringResource(R.string.template_email)) },
|
||||
label = { Text(text = stringResource(R.string.email)) }
|
||||
)
|
||||
RegistrationTextField(
|
||||
value = register.value.password,
|
||||
onChangeValue = { registrationViewModel.setPassword(it) },
|
||||
isError = false,
|
||||
supportingText = { Text(text = stringResource(R.string.wrong_password)) },
|
||||
placeholder = { Text(text = stringResource(R.string.template_password)) },
|
||||
label = { Text(text = stringResource(R.string.password)) }
|
||||
)
|
||||
|
||||
SimpleCheckbox()
|
||||
|
||||
RegistrationBtn(onClick = {
|
||||
registrationViewModel.registration(
|
||||
onSuccess = {
|
||||
onRegistrationSuccess()
|
||||
},
|
||||
onError = { errorMessage ->
|
||||
|
||||
onRegistrationError(errorMessage)
|
||||
}
|
||||
)
|
||||
}
|
||||
) {
|
||||
Text(text = stringResource(R.string.sign_up_on_reg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SimpleCheckbox(){
|
||||
val isChecked = remember { mutableStateOf(false) }
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
){
|
||||
Checkbox(
|
||||
checked = isChecked.value,
|
||||
onCheckedChange = {isChecked.value = it}
|
||||
)
|
||||
ClickableText(
|
||||
text = AnnotatedString(
|
||||
"Даю согласие на обработку персональных данных"
|
||||
),
|
||||
onClick={},
|
||||
style = MatuleTheme.typography.bodyRegular16.copy(color = MatuleTheme.colors.text),
|
||||
modifier = Modifier.padding(start = 8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.forgotscreen
|
||||
package com.example.shoesapptest.ui.screen.forgotscreen
|
||||
|
||||
data class ChangePass(
|
||||
var email: String = "",
|
@ -38,14 +38,15 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.input.pointer.motionEventSpy
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.example.shoesapptest.screen.forgotscreen.ForgotPasswordViewModel
|
||||
import com.example.shoesapptest.screen.forgotscreen.component.TitleWithSubtitleText
|
||||
import com.example.shoesapptest.screen.forgotscreen.component.EmailTextField
|
||||
import com.example.shoesapptest.screen.forgotscreen.component.SendButton
|
||||
import androidx.navigation.NavController
|
||||
import com.example.shoesapptest.ui.screen.forgotscreen.ForgotPasswordViewModel
|
||||
import com.example.shoesapptest.ui.screen.forgotscreen.component.TitleWithSubtitleText
|
||||
import com.example.shoesapptest.ui.screen.forgotscreen.component.EmailTextField
|
||||
import com.example.shoesapptest.ui.screen.forgotscreen.component.SendButton
|
||||
|
||||
|
||||
@Composable
|
||||
fun ForgotPasswordScreen(){
|
||||
fun ForgotPasswordScreen(onNavigateToSignInScreen: () -> Unit) {
|
||||
val forgotPasswordViewModel: ForgotPasswordViewModel = viewModel()
|
||||
val showDialog = remember { mutableStateOf(false) }
|
||||
|
||||
@ -142,25 +143,3 @@ fun CheckEmailDialog(onDismiss: () -> Unit) {
|
||||
containerColor = Color.White
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,16 +1,19 @@
|
||||
package com.example.shoesapptest.screen.forgotscreen
|
||||
package com.example.shoesapptest.ui.screen.forgotscreen
|
||||
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
class ForgotPasswordViewModel {
|
||||
class ForgotPasswordViewModel: ViewModel(){
|
||||
var changePass = mutableStateOf(ChangePass())
|
||||
private set
|
||||
|
||||
val emailHasError = derivedStateOf {
|
||||
if(changePass.value.email.isEmpty()) return@derivedStateOf false
|
||||
!android.util.Patterns.EMAIL_ADDRESS.matcher(changePass.value.email).matches()
|
||||
}
|
||||
|
||||
fun setEmail(email: String){
|
||||
changePass.value = changePass.value.copy(email=email)
|
||||
changePass.value = changePass.value.copy(email = email)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.forgotscreen.component
|
||||
package com.example.shoesapptest.ui.screen.forgotscreen.component
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.forgotscreen.component
|
||||
package com.example.shoesapptest.ui.screen.forgotscreen.component
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ButtonColors
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.forgotscreen.component
|
||||
package com.example.shoesapptest.ui.screen.forgotscreen.component
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
@ -0,0 +1,16 @@
|
||||
package com.example.shoesapptest.ui.screen.registrationscreen
|
||||
|
||||
import android.provider.ContactsContract.CommonDataKinds.Email
|
||||
import com.example.shoesapptest.ui.screen.forgotscreen.ChangePass
|
||||
import java.lang.Error
|
||||
|
||||
data class Registration(
|
||||
var email: String = "",
|
||||
var name: String = "",
|
||||
var password: String = "",
|
||||
var isVisiblePassword: Boolean = false,
|
||||
var errorMessage: String? = null,
|
||||
var isLoading: Boolean = false,
|
||||
var isSignedIn: Boolean = false,
|
||||
var emailHasError: Boolean = false
|
||||
)
|
@ -0,0 +1,192 @@
|
||||
package com.example.shoesapptest.screen.regscreen
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.ClickableText
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.example.shoesapp.ui.theme.MatuleTheme
|
||||
import com.example.shoesapptest.R
|
||||
import com.example.shoesapptest.ui.screen.registrationscreen.RegistrationViewModel
|
||||
import com.example.shoesapptest.ui.screen.registrationscreen.component.RegistrationBtn
|
||||
import com.example.shoesapptest.ui.screen.registrationscreen.component.RegistrationTextField
|
||||
import com.example.shoesapptest.ui.screen.registrationscreen.component.TextWithSubTitle
|
||||
import org.koin.compose.viewmodel.koinViewModel
|
||||
|
||||
|
||||
@Composable
|
||||
fun RegistrationScreen(
|
||||
onNavigationToSigninScreen: () -> Unit,
|
||||
viewModel: RegistrationViewModel = koinViewModel()
|
||||
) {
|
||||
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
|
||||
Scaffold(
|
||||
snackbarHost = { SnackbarHost(snackbarHostState) },
|
||||
topBar = {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(top = 35.dp)
|
||||
.fillMaxWidth()
|
||||
.height(40.dp)
|
||||
) {
|
||||
IconButton(onClick = onNavigationToSigninScreen) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.back_arrow),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
bottomBar = {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 50.dp)
|
||||
.fillMaxWidth()
|
||||
.height(40.dp)
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null
|
||||
) { onNavigationToSigninScreen() },
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = "Есть аккаунт? Войти",
|
||||
style = MatuleTheme.typography.bodyRegular16.copy(color = MatuleTheme.colors.text),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
) { paddingValues ->
|
||||
val state = viewModel.registration.value
|
||||
|
||||
LaunchedEffect(state.isSignedIn) {
|
||||
if (state.isSignedIn) {
|
||||
onNavigationToSigninScreen()
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(state.errorMessage) {
|
||||
state.errorMessage?.let {
|
||||
snackbarHostState.showSnackbar(it)
|
||||
viewModel.setErrorMessage(null)
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(paddingValues)
|
||||
.fillMaxWidth()
|
||||
.padding(20.dp)
|
||||
) {
|
||||
TextWithSubTitle(
|
||||
title = "Регистрация",
|
||||
subtitle = "Заполните Свои данные или продолжите через социальные медиа"
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
RegistrationTextField(
|
||||
value = state.name,
|
||||
onChangeValue = { viewModel.setUserName(it) },
|
||||
isError = false,
|
||||
supportingText = { Text(text = "Неверное имя пользователя") },
|
||||
placeholder = { Text(text = stringResource(R.string.template_password)) },
|
||||
label = { Text(text = "Ваше имя") }
|
||||
)
|
||||
|
||||
RegistrationTextField(
|
||||
value = state.email,
|
||||
onChangeValue = { viewModel.setEmail(it) },
|
||||
isError = state.emailHasError,
|
||||
supportingText = { Text(text = stringResource(R.string.wrong_email)) },
|
||||
placeholder = { Text(text = stringResource(R.string.template_email)) },
|
||||
label = { Text(text = stringResource(R.string.email)) },
|
||||
)
|
||||
|
||||
RegistrationTextField(
|
||||
value = state.password,
|
||||
onChangeValue = { viewModel.setPassword(it) },
|
||||
isError = false,
|
||||
supportingText = { Text(text = stringResource(R.string.wrong_password)) },
|
||||
placeholder = { Text(text = stringResource(R.string.template_password)) },
|
||||
label = { Text(text = stringResource(R.string.password)) }
|
||||
)
|
||||
|
||||
SimpleCheckbox()
|
||||
|
||||
RegistrationBtn(onClick = { viewModel.registration { } }) {
|
||||
if (state.isLoading) {
|
||||
CircularProgressIndicator()
|
||||
} else {
|
||||
Text(text = stringResource(R.string.sign_up_on_reg))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SimpleCheckbox() {
|
||||
val isChecked = remember { mutableStateOf(false) }
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Checkbox(
|
||||
checked = isChecked.value,
|
||||
onCheckedChange = { isChecked.value = it }
|
||||
)
|
||||
Text(
|
||||
text = "Даю согласие на обработку персональных данных",
|
||||
style = MatuleTheme.typography.bodyRegular16.copy(color = MatuleTheme.colors.text),
|
||||
modifier = Modifier.padding(start = 8.dp)
|
||||
)
|
||||
}
|
||||
}
|
@ -1,18 +1,18 @@
|
||||
package com.example.shoesapptest.screen.registrationscreen
|
||||
package com.example.shoesapptest.ui.screen.registrationscreen
|
||||
|
||||
import androidx.compose.animation.core.animateDecay
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.shoesapptest.data.model.RegistrationRequest
|
||||
import com.example.shoesapptest.data.repository.AuthRepository
|
||||
import com.example.shoesapptest.data.remote.dto.request.RegistrationRequest
|
||||
import com.example.shoesapptest.data.AuthRepository
|
||||
import com.example.shoesapptest.screen.regscreen.RegistrationScreen
|
||||
import kotlinx.coroutines.launch
|
||||
import java.lang.Error
|
||||
|
||||
class RegistrationViewModel(
|
||||
private val authRepository: AuthRepository
|
||||
):ViewModel() {
|
||||
|
||||
var registration = mutableStateOf(Registration())
|
||||
private set
|
||||
val emailHasError = derivedStateOf {
|
||||
@ -28,7 +28,10 @@ class RegistrationViewModel(
|
||||
fun setUserName(name: String){
|
||||
registration.value = registration.value.copy(name=name)
|
||||
}
|
||||
fun registration(onSuccess: () -> Unit, onError: (String) -> Unit){
|
||||
fun setErrorMessage(message: String?){
|
||||
registration.value=registration.value.copy(errorMessage = message)
|
||||
}
|
||||
fun registration(onSuccess: () -> Unit){
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val registrationRequest = RegistrationRequest(
|
||||
@ -36,11 +39,9 @@ class RegistrationViewModel(
|
||||
email = registration.value.email,
|
||||
password = registration.value.password
|
||||
)
|
||||
|
||||
authRepository.registration(registrationRequest)
|
||||
onSuccess()
|
||||
} catch (e: Exception) {
|
||||
onError(e.message ?: "Ошибка регистрации")
|
||||
registration.value = registration.value.copy(errorMessage = "Ошибка регистрации: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.registrationscreen.component
|
||||
package com.example.shoesapptest.ui.screen.registrationscreen.component
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ButtonColors
|
||||
@ -11,8 +11,8 @@ import com.example.shoesapptest.common.CommonButton
|
||||
@Composable
|
||||
fun RegistrationBtn(
|
||||
onClick: () -> Unit,
|
||||
content: @Composable () -> Unit
|
||||
){
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable () -> Unit){
|
||||
CommonButton(
|
||||
modifier = Modifier.padding(50.dp),
|
||||
onClick = onClick,
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.registrationscreen.component
|
||||
package com.example.shoesapptest.ui.screen.registrationscreen.component
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@ -8,7 +8,6 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.Placeholder
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.datastore.preferences.protobuf.Internal.BooleanList
|
||||
import com.example.shoesapptest.common.CommonTextField
|
||||
import java.lang.Error
|
||||
|
||||
@ -21,7 +20,7 @@ fun RegistrationTextField(
|
||||
placeholder: @Composable () -> Unit,
|
||||
label: @Composable () -> Unit
|
||||
){
|
||||
Column(Modifier.padding(50.dp)
|
||||
Column(Modifier.padding(horizontal = 20.dp)
|
||||
.wrapContentSize(),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)){
|
||||
label()
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.registrationscreen.component
|
||||
package com.example.shoesapptest.ui.screen.registrationscreen.component
|
||||
|
||||
import android.icu.text.CaseMap.Title
|
||||
import androidx.compose.foundation.layout.Arrangement
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.signin
|
||||
package com.example.shoesapptest.ui.screen.signin
|
||||
|
||||
data class SignInState (
|
||||
var email: String = "",
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.signin
|
||||
package com.example.shoesapptest.ui.screen.signin
|
||||
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
@ -1,7 +1,7 @@
|
||||
package com.example.shoesapp.ui.screen
|
||||
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@ -15,8 +15,7 @@ import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonColors
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
@ -24,10 +23,8 @@ import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
@ -40,16 +37,17 @@ import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import com.example.shoesapp.ui.theme.MatuleTheme
|
||||
import com.example.shoesapptest.R
|
||||
import com.example.shoesapptest.screen.signin.SignInViewMode
|
||||
import com.example.shoesapptest.screen.signin.component.AuthButton
|
||||
import com.example.shoesapptest.screen.signin.component.AuthTextField
|
||||
import com.example.shoesapptest.screen.signin.component.TitleWithSubtitleText
|
||||
|
||||
import com.example.shoesapptest.common.CommonButton
|
||||
import com.example.shoesapptest.ui.screen.signin.SignInViewMode
|
||||
import com.example.shoesapptest.ui.screen.signin.component.AuthButton
|
||||
import com.example.shoesapptest.ui.screen.signin.component.AuthTextField
|
||||
import com.example.shoesapptest.ui.screen.signin.component.TitleWithSubtitleText
|
||||
|
||||
@Composable
|
||||
fun SigninScreen() {
|
||||
fun SigninScreen(onNavigationToRegScreen: () -> Unit, navController: NavController) {
|
||||
val signInViewModel: SignInViewMode = viewModel()
|
||||
Scaffold(
|
||||
topBar = {
|
||||
@ -79,17 +77,18 @@ fun SigninScreen() {
|
||||
Text(
|
||||
stringResource(R.string.sign_up),
|
||||
style = MatuleTheme.typography.bodyRegular16.copy(color = MatuleTheme.colors.text),
|
||||
textAlign = TextAlign.Center
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.clickable { onNavigationToRegScreen() }
|
||||
)
|
||||
}
|
||||
}
|
||||
) { paddingValues ->
|
||||
SignInContent(paddingValues, signInViewModel)
|
||||
SignInContent(paddingValues, signInViewModel, navController)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SignInContent(paddingValues: PaddingValues, signInViewMode: SignInViewMode) {
|
||||
fun SignInContent(paddingValues: PaddingValues, signInViewMode: SignInViewMode, navController: NavController) {
|
||||
val signInState = signInViewMode.signInState
|
||||
Column(
|
||||
modifier = Modifier.padding(paddingValues = paddingValues),
|
||||
@ -101,28 +100,45 @@ fun SignInContent(paddingValues: PaddingValues, signInViewMode: SignInViewMode)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(35.dp))
|
||||
|
||||
|
||||
AuthTextField(
|
||||
value = signInState.value.email,
|
||||
onChangeValue = { signInViewMode.setEmail(it) },
|
||||
isError = signInViewMode.emailHasError.value,
|
||||
supportingText = { Text(text = stringResource(R.string.wrong_email))},
|
||||
placeholder = { Text(text = stringResource(R.string.template_email)) },
|
||||
label = { Text(text = stringResource(R.string.email))
|
||||
}
|
||||
label = { Text(text = stringResource(R.string.email)) }
|
||||
)
|
||||
|
||||
AuthTextField(
|
||||
value = signInState.value.password,
|
||||
onChangeValue = { signInViewMode.setPassword(it)},
|
||||
onChangeValue = { signInViewMode.setPassword(it) },
|
||||
isError = false,
|
||||
supportingText = { Text(text = "Неверный пароль")},
|
||||
placeholder = { Text(text = stringResource(R.string.template_password))},
|
||||
label = { Text(text = stringResource(R.string.password))}
|
||||
placeholder = { Text(text = stringResource(R.string.template_password)) },
|
||||
label = { Text(text = stringResource(R.string.password)) }
|
||||
)
|
||||
|
||||
|
||||
Text(
|
||||
text = "Забыл пароль",
|
||||
style = MatuleTheme.typography.bodyRegular16.copy(color = MatuleTheme.colors.text),
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
navController.navigate("forgotpass")
|
||||
}
|
||||
.padding(top = 8.dp)
|
||||
)
|
||||
|
||||
AuthButton(onClick = {}) {
|
||||
Text(stringResource(R.string.sign_in))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.signin.component
|
||||
package com.example.shoesapptest.ui.screen.signin.component
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ButtonColors
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.signin.component
|
||||
package com.example.shoesapptest.ui.screen.signin.component
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
@ -1,4 +1,4 @@
|
||||
package com.example.shoesapptest.screen.signin.component
|
||||
package com.example.shoesapptest.ui.screen.signin.component
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
Loading…
Reference in New Issue
Block a user