add swipe refresh to profile and start crating admin panel
This commit is contained in:
parent
0d24787c17
commit
e0e8ee0d58
@ -7,7 +7,7 @@ junitVersion = "1.2.1"
|
|||||||
espressoCore = "3.6.1"
|
espressoCore = "3.6.1"
|
||||||
lifecycleRuntimeKtx = "2.8.7"
|
lifecycleRuntimeKtx = "2.8.7"
|
||||||
activityCompose = "1.10.0"
|
activityCompose = "1.10.0"
|
||||||
composeBom = "2024.04.01"
|
composeBom = "2024.09.03"
|
||||||
|
|
||||||
kapt = "2.1.10"
|
kapt = "2.1.10"
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import androidx.navigation.NavHostController
|
|||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import com.nto.data.utils.Destinations
|
import com.nto.data.utils.Destinations
|
||||||
|
import com.nto.presentation.screens.admin.AdminScreen
|
||||||
import com.nto.presentation.screens.loginScreen.LoginScreen
|
import com.nto.presentation.screens.loginScreen.LoginScreen
|
||||||
import com.nto.presentation.screens.profileScreen.ProfileScreen
|
import com.nto.presentation.screens.profileScreen.ProfileScreen
|
||||||
import com.nto.presentation.screens.scanResult.ScanResultScreen
|
import com.nto.presentation.screens.scanResult.ScanResultScreen
|
||||||
@ -15,7 +16,7 @@ fun Navigation(navController: NavHostController, modifier: Modifier = Modifier)
|
|||||||
NavHost(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
startDestination = Destinations.Login
|
startDestination = Destinations.Profile
|
||||||
) {
|
) {
|
||||||
composable<Destinations.Login> {
|
composable<Destinations.Login> {
|
||||||
LoginScreen(navController)
|
LoginScreen(navController)
|
||||||
@ -27,7 +28,7 @@ fun Navigation(navController: NavHostController, modifier: Modifier = Modifier)
|
|||||||
ScanResultScreen(navController)
|
ScanResultScreen(navController)
|
||||||
}
|
}
|
||||||
composable<Destinations.Admin> {
|
composable<Destinations.Admin> {
|
||||||
//TODO
|
AdminScreen(navController)
|
||||||
}
|
}
|
||||||
composable<Destinations.Options> {
|
composable<Destinations.Options> {
|
||||||
//TODO
|
//TODO
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
package com.nto.presentation.screens.admin
|
||||||
|
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
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.size
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
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 com.nto.data.utils.Destinations
|
||||||
|
import com.nto.presentation.R
|
||||||
|
import com.nto.presentation.composable.InputField
|
||||||
|
import com.nto.presentation.theme.NTOTheme
|
||||||
|
import com.nto.presentation.theme.playfair
|
||||||
|
import com.nto.presentation.theme.raleway
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AdminScreen(
|
||||||
|
navController: NavController,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
viewModel: AdminViewModel = hiltViewModel()
|
||||||
|
) {
|
||||||
|
Scaffold { innerPaddings ->
|
||||||
|
Column(
|
||||||
|
Modifier
|
||||||
|
.padding(innerPaddings)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 24.dp)
|
||||||
|
) {
|
||||||
|
Spacer(Modifier.height(36.dp))
|
||||||
|
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.admin_header),
|
||||||
|
fontFamily = playfair,
|
||||||
|
color = NTOTheme.colors.primaryText,
|
||||||
|
fontSize = 32.sp,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
navController.popBackStack()
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.size(44.dp)
|
||||||
|
.border(BorderStroke(2.dp, NTOTheme.colors.buttonDisabled), CircleShape),
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(R.drawable.ic_arrow_back),
|
||||||
|
contentDescription = ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer(Modifier.height(20.dp))
|
||||||
|
Text(
|
||||||
|
stringResource(R.string.text_login),
|
||||||
|
fontFamily = raleway,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
color = NTOTheme.colors.primaryText,
|
||||||
|
modifier = Modifier.padding(start = 10.dp),
|
||||||
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(5.dp))
|
||||||
|
InputField(
|
||||||
|
viewModel.login,
|
||||||
|
placeholder = stringResource(R.string.placholder_login),
|
||||||
|
onValueChange = viewModel::setLogin
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.nto.presentation.screens.admin
|
||||||
|
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class AdminViewModel @Inject constructor(): ViewModel() {
|
||||||
|
private var _login by mutableStateOf("")
|
||||||
|
|
||||||
|
val login get() = _login
|
||||||
|
|
||||||
|
fun setLogin(value: String) {
|
||||||
|
_login = value
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,11 @@
|
|||||||
package com.nto.presentation.screens.profileScreen
|
package com.nto.presentation.screens.profileScreen
|
||||||
|
|
||||||
import android.content.ContentValues.TAG
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@ -19,11 +17,16 @@ import androidx.compose.foundation.layout.size
|
|||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.IconButtonDefaults
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
@ -41,8 +44,8 @@ import androidx.navigation.NavController
|
|||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.journeyapps.barcodescanner.ScanContract
|
import com.journeyapps.barcodescanner.ScanContract
|
||||||
import com.journeyapps.barcodescanner.ScanOptions
|
import com.journeyapps.barcodescanner.ScanOptions
|
||||||
import com.nto.presentation.CustomCaptureActivity
|
|
||||||
import com.nto.data.utils.Destinations
|
import com.nto.data.utils.Destinations
|
||||||
|
import com.nto.presentation.CustomCaptureActivity
|
||||||
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
|
||||||
@ -51,6 +54,7 @@ import com.nto.presentation.theme.TextGray
|
|||||||
import com.nto.presentation.theme.playfair
|
import com.nto.presentation.theme.playfair
|
||||||
import com.nto.presentation.theme.raleway
|
import com.nto.presentation.theme.raleway
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ProfileScreen(
|
fun ProfileScreen(
|
||||||
navController: NavController,
|
navController: NavController,
|
||||||
@ -58,7 +62,6 @@ fun ProfileScreen(
|
|||||||
viewModel: ProfileViewModel = hiltViewModel<ProfileViewModel>(),
|
viewModel: ProfileViewModel = hiltViewModel<ProfileViewModel>(),
|
||||||
) {
|
) {
|
||||||
val state = viewModel.state.collectAsState().value
|
val state = viewModel.state.collectAsState().value
|
||||||
|
|
||||||
val scannerLauncher = rememberLauncherForActivityResult(
|
val scannerLauncher = rememberLauncherForActivityResult(
|
||||||
contract = ScanContract(),
|
contract = ScanContract(),
|
||||||
onResult = { result -> navController.navigate(Destinations.Scan(result.contents)) }
|
onResult = { result -> navController.navigate(Destinations.Scan(result.contents)) }
|
||||||
@ -75,199 +78,201 @@ fun ProfileScreen(
|
|||||||
navController.navigate(Destinations.Login)
|
navController.navigate(Destinations.Login)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PullToRefreshBox(
|
||||||
Column(
|
isRefreshing = viewModel.isLoading,
|
||||||
modifier = modifier.background(NTOTheme.colors.primaryBackground)
|
onRefresh = {
|
||||||
|
viewModel.updateInfo()
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.fillMaxSize()
|
.background(NTOTheme.colors.primaryBackground)
|
||||||
.padding(start = 20.dp, end = 20.dp)
|
|
||||||
) {
|
) {
|
||||||
Spacer(modifier = Modifier.height(10.dp))
|
Column(
|
||||||
Column(modifier = Modifier.weight(1f)) {
|
modifier = Modifier
|
||||||
Row(
|
.fillMaxSize()
|
||||||
modifier = Modifier.fillMaxWidth(),
|
.padding(start = 20.dp, end = 20.dp)
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
.verticalScroll(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
rememberScrollState()
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
stringResource(R.string.title_profile),
|
|
||||||
fontFamily = playfair,
|
|
||||||
color = NTOTheme.colors.primaryText,
|
|
||||||
fontSize = 32.sp,
|
|
||||||
fontWeight = FontWeight.Bold
|
|
||||||
)
|
)
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
) {
|
||||||
Box(
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
modifier = Modifier
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
.size(35.dp)
|
Row(
|
||||||
.clip(CircleShape)
|
modifier = Modifier.fillMaxWidth(),
|
||||||
.border(2.dp, NTOTheme.colors.buttonAdmin, shape = CircleShape),
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
contentAlignment = Alignment.Center
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
IconButton(modifier = Modifier.size(25.dp), onClick = {
|
Text(
|
||||||
viewModel.admin(navController)
|
stringResource(R.string.title_profile),
|
||||||
}) {
|
fontFamily = playfair,
|
||||||
|
color = NTOTheme.colors.primaryText,
|
||||||
|
fontSize = 32.sp,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
navController.navigate(Destinations.Admin)
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.size(44.dp)
|
||||||
|
.border(
|
||||||
|
BorderStroke(2.dp, NTOTheme.colors.buttonAdmin),
|
||||||
|
CircleShape
|
||||||
|
),
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(R.drawable.icon_admin),
|
painter = painterResource(R.drawable.icon_admin),
|
||||||
modifier = Modifier.size(20.dp),
|
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = NTOTheme.colors.buttonAdmin
|
tint = NTOTheme.colors.buttonAdmin
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
IconButton(
|
||||||
Box(
|
onClick = {},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(35.dp)
|
.size(44.dp)
|
||||||
.clip(CircleShape)
|
.border(
|
||||||
.border(2.dp, NTOTheme.colors.buttonDisabled, shape = CircleShape),
|
BorderStroke(2.dp, NTOTheme.colors.buttonDisabled),
|
||||||
contentAlignment = Alignment.Center
|
CircleShape
|
||||||
) {
|
)
|
||||||
IconButton(modifier = Modifier.size(25.dp), onClick = {
|
) {
|
||||||
viewModel.option(navController)
|
|
||||||
}) {
|
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(R.drawable.icon_options),
|
painter = painterResource(R.drawable.icon_options),
|
||||||
modifier = Modifier.size(20.dp),
|
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = NTOTheme.colors.buttonDisabled
|
tint = NTOTheme.colors.buttonDisabled
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
Spacer(modifier = Modifier.width(14.dp))
|
IconButton(
|
||||||
Box(
|
modifier = Modifier.size(44.dp), onClick = {
|
||||||
modifier = Modifier
|
viewModel.logout(navController)
|
||||||
.size(35.dp)
|
}, colors = IconButtonDefaults.iconButtonColors(
|
||||||
.clip(CircleShape)
|
containerColor = NTOTheme.colors.buttonDisabled
|
||||||
.background(NTOTheme.colors.buttonDisabled),
|
)
|
||||||
contentAlignment = Alignment.Center
|
) {
|
||||||
) {
|
|
||||||
IconButton(modifier = Modifier.size(25.dp), onClick = {
|
|
||||||
viewModel.logout(navController)
|
|
||||||
}) {
|
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(R.drawable.icon_logout),
|
painter = painterResource(R.drawable.icon_logout),
|
||||||
modifier = Modifier.size(20.dp),
|
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = NTOTheme.colors.primaryBackground
|
tint = NTOTheme.colors.primaryBackground
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(50.dp))
|
Spacer(modifier = Modifier.height(50.dp))
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(R.drawable.logo_placeholder_user),
|
painter = painterResource(R.drawable.logo_placeholder_user),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(100.dp)
|
.size(100.dp)
|
||||||
.clip(
|
.clip(
|
||||||
CircleShape
|
CircleShape
|
||||||
),
|
),
|
||||||
contentDescription = null
|
contentDescription = null
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(15.dp))
|
Spacer(modifier = Modifier.width(15.dp))
|
||||||
Column(
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(RoundedCornerShape(10.dp))
|
||||||
|
.background(NTOTheme.colors.inputFieldBackground)
|
||||||
|
.padding(10.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
state.secondName,
|
||||||
|
fontFamily = raleway,
|
||||||
|
color = NTOTheme.colors.primaryText,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
lineHeight = 16.sp
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
state.firstName,
|
||||||
|
fontFamily = raleway,
|
||||||
|
color = NTOTheme.colors.primaryText,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
lineHeight = 16.sp
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
state.thirdName,
|
||||||
|
fontFamily = raleway,
|
||||||
|
color = NTOTheme.colors.primaryText,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
lineHeight = 16.sp
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
Text(
|
||||||
|
state.job,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontFamily = raleway,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
color = TextGray
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(20.dp))
|
||||||
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
.height(35.dp)
|
||||||
.clip(RoundedCornerShape(10.dp))
|
.clip(RoundedCornerShape(10.dp))
|
||||||
.background(NTOTheme.colors.inputFieldBackground)
|
.background(NTOTheme.colors.inputFieldBackground)
|
||||||
.padding(10.dp)
|
.padding(start = 15.dp, end = 15.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
state.secondName,
|
stringResource(R.string.label_last_visit),
|
||||||
fontFamily = raleway,
|
|
||||||
color = NTOTheme.colors.primaryText,
|
|
||||||
fontSize = 16.sp,
|
|
||||||
fontWeight = FontWeight.SemiBold,
|
|
||||||
lineHeight = 16.sp
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
state.firstName,
|
|
||||||
fontFamily = raleway,
|
|
||||||
color = NTOTheme.colors.primaryText,
|
|
||||||
fontSize = 16.sp,
|
|
||||||
fontWeight = FontWeight.SemiBold,
|
|
||||||
lineHeight = 16.sp
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
state.thirdName,
|
|
||||||
fontFamily = raleway,
|
|
||||||
color = NTOTheme.colors.primaryText,
|
|
||||||
fontSize = 16.sp,
|
|
||||||
fontWeight = FontWeight.SemiBold,
|
|
||||||
lineHeight = 16.sp
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
Text(
|
|
||||||
state.job,
|
|
||||||
fontWeight = FontWeight.Medium,
|
fontWeight = FontWeight.Medium,
|
||||||
fontFamily = raleway,
|
fontFamily = raleway,
|
||||||
fontSize = 14.sp,
|
color = NTOTheme.colors.primaryText,
|
||||||
color = TextGray
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
state.lastOpen,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontFamily = raleway,
|
||||||
|
color = NTOTheme.colors.primaryText,
|
||||||
|
fontSize = 14.sp
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
Spacer(modifier = Modifier.height(20.dp))
|
||||||
Spacer(modifier = Modifier.height(20.dp))
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(35.dp)
|
|
||||||
.clip(RoundedCornerShape(10.dp))
|
|
||||||
.background(NTOTheme.colors.inputFieldBackground)
|
|
||||||
.padding(start = 15.dp, end = 15.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
|
||||||
Text(
|
Text(
|
||||||
stringResource(R.string.label_last_visit),
|
stringResource(R.string.label_visits),
|
||||||
fontWeight = FontWeight.Medium,
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
fontSize = 20.sp,
|
||||||
fontFamily = raleway,
|
fontFamily = raleway,
|
||||||
color = NTOTheme.colors.primaryText,
|
color = NTOTheme.colors.primaryText
|
||||||
fontSize = 14.sp
|
|
||||||
)
|
)
|
||||||
Text(
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
state.lastOpen,
|
|
||||||
fontWeight = FontWeight.Normal,
|
|
||||||
fontFamily = raleway,
|
|
||||||
color = NTOTheme.colors.primaryText,
|
|
||||||
fontSize = 14.sp
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Spacer(modifier = Modifier.height(20.dp))
|
|
||||||
Text(
|
|
||||||
stringResource(R.string.label_visits),
|
|
||||||
fontWeight = FontWeight.SemiBold,
|
|
||||||
fontSize = 20.sp,
|
|
||||||
fontFamily = raleway,
|
|
||||||
color = NTOTheme.colors.primaryText
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.height(10.dp))
|
|
||||||
|
|
||||||
LazyColumn(verticalArrangement = Arrangement.spacedBy(10.dp)) {
|
LazyColumn(verticalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||||
items(state.visits) { item ->
|
items(state.visits) { item ->
|
||||||
VisitCard(item)
|
VisitCard(item)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
DecoratedButton(
|
||||||
DecoratedButton(
|
stringResource(R.string.label_scan),
|
||||||
stringResource(R.string.label_scan),
|
false,
|
||||||
false,
|
modifier = Modifier
|
||||||
modifier = Modifier
|
.padding(bottom = 10.dp)
|
||||||
.padding(bottom = 10.dp)
|
.fillMaxWidth()
|
||||||
.fillMaxWidth()
|
.height(62.dp)
|
||||||
.height(62.dp)
|
) {
|
||||||
) {
|
scannerLauncher.launch(scanOptions)
|
||||||
scannerLauncher.launch(scanOptions)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.nto.presentation.screens.profileScreen
|
package com.nto.presentation.screens.profileScreen
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
@ -24,32 +27,19 @@ import javax.inject.Inject
|
|||||||
class ProfileViewModel @Inject constructor(
|
class ProfileViewModel @Inject constructor(
|
||||||
private val useCase: ProfileUseCase, @ApplicationContext private val context: Context
|
private val useCase: ProfileUseCase, @ApplicationContext private val context: Context
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
private val _state = MutableStateFlow(
|
private var _isLoading by mutableStateOf(false)
|
||||||
ProfileState(
|
private val _state = MutableStateFlow(ProfileState())
|
||||||
"Николай",
|
|
||||||
"Одегов",
|
|
||||||
"Алексеевич",
|
|
||||||
"20 января 2024 20:21",
|
|
||||||
"Senior UI/UX designer",
|
|
||||||
visits = listOf(
|
|
||||||
VisitCardDTO(
|
|
||||||
"Кабинет 207",
|
|
||||||
10020,
|
|
||||||
LocalDateTime.now(),
|
|
||||||
VisitType.CARD_ENTRY,
|
|
||||||
qrCode = QRDTO(12032, "Кобинет 52")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
val isLoading get() = _isLoading
|
||||||
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) {
|
||||||
|
_isLoading = true
|
||||||
val result = useCase.getInfo()
|
val result = useCase.getInfo()
|
||||||
_state.tryEmit(ProfileState().apply { deserialize(result, context) })
|
_state.tryEmit(ProfileState().apply { deserialize(result, context) })
|
||||||
|
_isLoading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
presentation/src/main/res/drawable/ic_arrow_back.xml
Normal file
9
presentation/src/main/res/drawable/ic_arrow_back.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M7.825,13L13.425,18.6L12,20L4,12L12,4L13.425,5.4L7.825,11H20V13H7.825Z"
|
||||||
|
android:fillColor="#CAD5CA"/>
|
||||||
|
</vector>
|
@ -22,4 +22,5 @@
|
|||||||
<string name="code_scanned_error">Enter was cancelled</string>
|
<string name="code_scanned_error">Enter was cancelled</string>
|
||||||
<string name="code_scanned_warning">Something went wrong</string>
|
<string name="code_scanned_warning">Something went wrong</string>
|
||||||
<string name="close">Close</string>
|
<string name="close">Close</string>
|
||||||
|
<string name="admin_header">Admin</string>
|
||||||
</resources>
|
</resources>
|
@ -23,4 +23,5 @@
|
|||||||
<string name="code_scanned_error">Вход был отменён</string>
|
<string name="code_scanned_error">Вход был отменён</string>
|
||||||
<string name="code_scanned_warning">Что-то пошло не так</string>
|
<string name="code_scanned_warning">Что-то пошло не так</string>
|
||||||
<string name="close">Закрыть</string>
|
<string name="close">Закрыть</string>
|
||||||
|
<string name="admin_header">Управление</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user