Procházet zdrojové kódy

add: add new screen - Profile and his viewModel, there is an output of an image and basic user information; update: navigation and bottom bar

Maksutka před 2 dny
rodič
revize
0c95ac6cfe

+ 3 - 1
TripHelper/app/src/main/java/com/example/triphelper/view/AppBar/bottombar/BottomBar.kt

@@ -150,7 +150,9 @@ fun BottomBar(controller: NavController,
                             .weight(0.9f, true)
                     ) {
                         IconButton(
-                            onClick = {},
+                            onClick = {
+                                controller.navigate(NavigationRoutes.PROF_USER)
+                            },
                             modifier = Modifier
                                 .size(50.dp)
                         ) {

+ 198 - 0
TripHelper/app/src/main/java/com/example/triphelper/view/ProfileScreen/ProfileUser.kt

@@ -0,0 +1,198 @@
+package com.example.triphelper.view.ProfileScreen
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+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.layout.ContentScale
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.navigation.NavController
+import coil.compose.AsyncImagePainter
+import coil.compose.rememberAsyncImagePainter
+import coil.request.ImageRequest
+import com.example.testirovanye_supabase.R
+import com.example.triphelper.view.navigation.NavigationRoutes
+import com.example.triphelper.view.style.StyleMainFone
+import com.example.triphelper.view.theme.SeoulBold
+
+@Composable
+fun ProfileUser(
+    navController: NavController, iconsProfileIsActivity: MutableState<Boolean>, viewModel: ProfileViewModel = hiltViewModel()) {
+    iconsProfileIsActivity.value = true
+    val users by viewModel.users.collectAsState(initial = emptyList())
+    val titleCountry by viewModel.titleCountry.collectAsState(initial = null)
+    val email by viewModel.userEmail.collectAsState(initial = null)
+    var imageState: AsyncImagePainter.State
+
+    StyleMainFone()
+    LaunchedEffect(key1 = viewModel.navigationTo) {
+        viewModel.navigationTo.collect { destination ->
+            destination?.let {
+                navController.navigate(destination)
+            }
+        }
+
+    }
+    viewModel.GetUser()
+    if (users.isNotEmpty()) {
+        users.firstOrNull().let { item ->
+            viewModel.getTitleCountry(item?.country)
+            if (item?.avatar == null) {
+                imageState = rememberAsyncImagePainter(
+                    model = ImageRequest.Builder(LocalContext.current).data(R.drawable.no_avatar)
+                        .size(coil.size.Size.ORIGINAL).build()
+                ).state
+            } else {
+                imageState = rememberAsyncImagePainter(
+                    model = ImageRequest.Builder(LocalContext.current).data(item.avatar)
+                        .size(coil.size.Size.ORIGINAL).build()
+                ).state
+            }
+            if (imageState is AsyncImagePainter.State.Error) {
+                Box(
+                    modifier = Modifier
+                        .fillMaxWidth()
+                        .height(200.dp),
+                    contentAlignment = Alignment.Center
+                ) {
+                    CircularProgressIndicator()
+                }
+            }
+            if (imageState is AsyncImagePainter.State.Success) {
+                Column(
+                    modifier = Modifier
+                        .fillMaxWidth()
+                        .fillMaxHeight(0.9f),
+                    verticalArrangement = Arrangement.Center,
+                    horizontalAlignment = Alignment.CenterHorizontally
+                ) {
+                    Column {
+                        imageState.painter?.let {
+                            Image(
+                                modifier = Modifier
+                                    .size(180.dp)
+                                    .clip(RoundedCornerShape(20.dp)),
+                                painter = it,
+                                contentDescription = ""
+                            )
+                        }
+                    }
+                    Column(
+                        modifier = Modifier.padding(top = 20.dp, bottom = 20.dp)
+                    ){
+                        if (item != null) {
+                            Text(
+                                text = item.name,
+                                fontSize = 32.sp,
+                                fontFamily = SeoulBold,
+                                fontWeight = FontWeight.Bold,
+                                color = Color(0xFF510B3C)
+                            )
+                        }
+                    }
+                    Box(
+                        modifier = Modifier
+                            .fillMaxWidth(0.8f)
+                            .fillMaxHeight(0.65f)
+                            .background(Color.White)
+                            .border(
+                                width = 3.dp,
+                                color = Color(0xFF510B3C)
+                            ),
+                        contentAlignment = Alignment.CenterStart
+                    ){
+                        Column(
+                            modifier = Modifier.padding(start = 20.dp),
+                            verticalArrangement = Arrangement.spacedBy(30.dp)
+                        ) {
+                            Column(
+                                verticalArrangement = Arrangement.spacedBy(15.dp)
+                            ) {
+                                Text(
+                                    text = "Почта",
+                                    fontSize = 32.sp,
+                                    fontFamily = SeoulBold,
+                                    fontWeight = FontWeight.Medium,
+                                    color = Color(0xFFDC5B6E)
+                                )
+                                Text(
+                                    modifier = Modifier.padding(start = 2.dp),
+                                    text = email.toString(),
+                                    fontSize = 24.sp,
+                                    fontFamily = SeoulBold,
+                                    fontWeight = FontWeight.Medium,
+                                    color = Color(0xFF510B3C)
+                                )
+                            }
+                            Column(
+                                verticalArrangement = Arrangement.spacedBy(15.dp)
+                            ) {
+                                Text(
+                                    text = "Пароль",
+                                    fontSize = 32.sp,
+                                    fontFamily = SeoulBold,
+                                    fontWeight = FontWeight.Medium,
+                                    color = Color(0xFFDC5B6E)
+                                )
+                                Text(
+                                    modifier = Modifier.padding(start = 2.dp),
+                                    text = "* * * * * * * *",
+                                    fontSize = 24.sp,
+                                    fontFamily = SeoulBold,
+                                    fontWeight = FontWeight.Medium,
+                                    color = Color(0xFF510B3C)
+                                )
+                            }
+                            Column(
+                                verticalArrangement = Arrangement.spacedBy(15.dp)
+                            ) {
+                                Text(
+                                    text = "Страна",
+                                    fontSize = 32.sp,
+                                    fontFamily = SeoulBold,
+                                    fontWeight = FontWeight.Medium,
+                                    color = Color(0xFFDC5B6E)
+                                )
+                                Text(
+                                    modifier = Modifier.padding(start = 2.dp),
+                                    text = titleCountry.toString(),
+                                    fontSize = 24.sp,
+                                    fontFamily = SeoulBold,
+                                    fontWeight = FontWeight.Medium,
+                                    color = Color(0xFF510B3C)
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

+ 80 - 0
TripHelper/app/src/main/java/com/example/triphelper/view/ProfileScreen/ProfileViewModel.kt

@@ -0,0 +1,80 @@
+package com.example.triphelper.view.ProfileScreen
+
+
+import android.util.Log
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.example.triphelper.domain.Constants
+import com.example.triphelper.model.Attractions
+import com.example.triphelper.model.Country
+import com.example.triphelper.model.Users
+import dagger.hilt.android.lifecycle.HiltViewModel
+import io.github.jan.supabase.gotrue.auth
+import io.github.jan.supabase.postgrest.from
+import io.github.jan.supabase.postgrest.query.Columns
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import javax.inject.Inject
+
+@HiltViewModel
+class ProfileViewModel@Inject constructor() : ViewModel() {
+    private var _navigationTo = MutableStateFlow<String?>(null) //Переменные для навигации страницы из авторизации на главный экран
+    val navigationTo = _navigationTo.asStateFlow()
+
+    private val _users: MutableStateFlow<List<Users>> = MutableStateFlow(listOf())
+    val users: StateFlow<List<Users>> = _users.asStateFlow()
+
+    private val _titleCountry = MutableStateFlow("")
+    val titleCountry: StateFlow<String> = _titleCountry.asStateFlow()
+
+    private val _userEmail = MutableStateFlow<String?>(null)
+    val userEmail: StateFlow<String?> = _userEmail.asStateFlow()
+
+    fun GetUser(){
+        viewModelScope.launch {
+            try {
+                withContext(Dispatchers.IO){
+                    val idUser = Constants.supabase.auth.currentUserOrNull()?.id.toString()
+                    val responce = Constants.supabase.from("users").select(){
+                        filter {
+                            eq("id", idUser)
+                        }
+                    }.decodeList<Users>()
+                    _users.value = responce
+                    val authUser = Constants.supabase.auth.currentUserOrNull()
+                    if (authUser != null) {
+                        _userEmail.value = authUser.email
+                    }
+                    Log.i("user", "${_users.value}")
+                }
+            }catch (e:Exception){
+                Log.e("GetUser", "Error retrieving user data", e)
+            }
+        }
+    }
+    fun getTitleCountry(idCountry: Int?) {
+        viewModelScope.launch {
+            try {
+                val response = Constants.supabase
+                    .from("country")
+                    .select {
+                        filter {
+                            if (idCountry != null) {
+                                eq("id", idCountry)
+                            }
+                        }
+                    }
+                    .decodeSingleOrNull<Country>()
+                _titleCountry.value = response?.title.toString()
+                Log.i("id", _titleCountry.value)
+
+            } catch (e: Exception) {
+                Log.e("getCountry", "Error retrieving country data", e)
+            }
+        }
+    }
+}

+ 11 - 1
TripHelper/app/src/main/java/com/example/triphelper/view/navigation/Navigation.kt

@@ -13,6 +13,7 @@ import com.example.triphelper.view.Auth.Auth
 import com.example.triphelper.view.LawScreen.DescriptionLaws
 import com.example.triphelper.view.MainScreen.LawScreen
 import com.example.triphelper.view.MainScreen.MainScreen
+import com.example.triphelper.view.ProfileScreen.ProfileUser
 import com.example.triphelper.view.Registration.Registration
 import com.example.triphelper.view.RouteScreens.AdviceScreen
 import com.example.triphelper.view.RouteScreens.AttractionsDesc
@@ -29,7 +30,7 @@ fun Navigation(controller: NavHostController, barsIsVisible: MutableState<Boolea
                iconsLawIsActivity: MutableState<Boolean>, iconsProfileIsActivity: MutableState<Boolean>,
                iconsAdviceIsActivity: MutableState<Boolean>,iconsMainIsActivity: MutableState<Boolean>, iconsRoutsIsActivity: MutableState<Boolean>) {
     NavHost(navController = controller,
-        startDestination = NavigationRoutes.ADVICE)
+        startDestination = NavigationRoutes.AUTH)
     {
         composable( NavigationRoutes.SPLASH){
             barsIsVisible.value = false
@@ -161,5 +162,14 @@ fun Navigation(controller: NavHostController, barsIsVisible: MutableState<Boolea
             iconsRoutsIsActivity.value = false
             AdviceScreen(controller, iconsAdviceIsActivity)
         }
+        composable(NavigationRoutes.PROF_USER){
+            barsIsVisible.value = true
+            iconsLawIsActivity.value = false
+            iconsAdviceIsActivity.value = false
+            iconsProfileIsActivity.value = false
+            iconsMainIsActivity.value = false
+            iconsRoutsIsActivity.value = false
+            ProfileUser(controller, iconsProfileIsActivity)
+        }
     }
 }

+ 1 - 0
TripHelper/app/src/main/java/com/example/triphelper/view/navigation/NavigationRoutes.kt

@@ -14,4 +14,5 @@ object NavigationRoutes {
     const val HOTEL_DESC = "hotelsdesc"
     const val REST_DESC = "restauransdesc"
     const val  ADVICE = "advice"
+    const val PROF_USER = "profileuser"
 }

binární
TripHelper/app/src/main/res/drawable/no_avatar.jpg