Такс, подшаманил дезигн, по сути остолось только 2........... Сделать прогрузку, валидацию и поиск(надеюсь, успею...)

This commit is contained in:
Кашин Максим 2023-12-26 22:32:27 +04:00
parent c7ffbb6ca5
commit c7f73c4d5a
4 changed files with 241 additions and 106 deletions

View File

@ -204,7 +204,7 @@ fun Navhost(
arguments = listOf(navArgument("id") { type = NavType.IntType }, arguments = listOf(navArgument("id") { type = NavType.IntType },
navArgument("bikeId") { type = NavType.IntType }) navArgument("bikeId") { type = NavType.IntType })
) { ) {
ItemEdit(navController) ItemEdit(navController,currentUserViewModel = currentUserViewModel)
} }
composable( composable(
Screen.BikeView.route, Screen.BikeView.route,

View File

@ -138,7 +138,7 @@ fun BikeView(
) { ) {
Icon( Icon(
imageVector = Icons.Filled.Add, imageVector = Icons.Filled.Add,
contentDescription = "Добавить сеанс", contentDescription = "Добавить",
) )
} }
} }

View File

@ -1,42 +1,68 @@
package com.example.myapplication.database.entities.composeui.edit package com.example.myapplication.database.entities.composeui.edit
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.util.Log
import androidx.compose.foundation.background
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.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.DatePicker import androidx.compose.material3.DatePicker
import androidx.compose.material3.DatePickerDefaults import androidx.compose.material3.DatePickerDefaults
import androidx.compose.material3.DisplayMode import androidx.compose.material3.DisplayMode
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.rememberDatePickerState import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.myapplication.R import com.example.myapplication.composeui.navigation.Screen
import com.example.myapplication.database.entities.composeui.AppViewModelProvider import com.example.myapplication.database.entities.composeui.AppViewModelProvider
import com.example.myapplication.database.entities.composeui.CurrentUserViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.threeten.bp.Instant import org.threeten.bp.Instant
import org.threeten.bp.LocalDateTime import org.threeten.bp.LocalDateTime
import org.threeten.bp.LocalTime import org.threeten.bp.LocalTime
import org.threeten.bp.ZoneId import org.threeten.bp.ZoneId
import org.threeten.bp.ZoneOffset import org.threeten.bp.ZoneOffset
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@Composable @Composable
fun ItemEdit( fun ItemEdit(
navController: NavController, navController: NavController,
viewModel: ItemEditViewModel = viewModel(factory = AppViewModelProvider.Factory), viewModel: ItemEditViewModel = viewModel(factory = AppViewModelProvider.Factory),
currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)
) { ) {
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
var getUser by remember { mutableStateOf(currentUserViewModel.user) }
if(getUser?.role == "admin"){
ItemEdit( ItemEdit(
itemUiState = viewModel.itemUiState, itemUiState = viewModel.itemUiState,
onClick = { onClick = {
@ -47,6 +73,42 @@ fun ItemEdit(
}, },
onUpdate = viewModel::updateUiState onUpdate = viewModel::updateUiState
) )
}
else{
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Column(
modifier = Modifier
.fillMaxSize()
.weight(1f), // Занимает все доступное пространство, кроме кнопки
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("На данный момент страница не доступна.", fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.height(8.dp))
Text("У вашего аккаунта не достаточно прав.")
}
Button(
onClick = {
coroutineScope.launch {
navController.popBackStack()
}
},
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
) {
Text("Выйти")
}
}
}
} }
fun Long.toLocalDate(): org.threeten.bp.LocalDate { fun Long.toLocalDate(): org.threeten.bp.LocalDate {
@ -62,45 +124,119 @@ private fun ItemEdit(
onClick: () -> Unit, onClick: () -> Unit,
onUpdate: (ItemDetails) -> Unit, onUpdate: (ItemDetails) -> Unit,
) { ) {
LazyColumn(
Modifier
.fillMaxWidth()
.padding(all = 10.dp)
) {
item {
if (itemUiState.itemDetails.dateTime != LocalDateTime.MIN) {
val selectedDateMillis =
itemUiState.itemDetails.dateTime.toInstant(ZoneOffset.UTC).toEpochMilli()
val dateState = rememberDatePickerState( Column(
initialDisplayMode = DisplayMode.Input, modifier = Modifier
initialSelectedDateMillis = selectedDateMillis .verticalScroll(rememberScrollState())
.padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Column(
modifier = Modifier
//.width(180.dp) // Adjust the width as needed
.fillMaxHeight()
.padding(8.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = "Вес",
textAlign = TextAlign.Center,
) )
/* Surface( Spacer(modifier = Modifier.height(4.dp))
tonalElevation = 6.dp, BasicTextField(
color = MaterialTheme.colorScheme.primary value = itemUiState.itemDetails.weight,
) {*/ onValueChange = { onUpdate(itemUiState.itemDetails.copy(weight = it)) },
DatePicker( modifier = Modifier
state = dateState, .fillMaxWidth()
modifier = Modifier.padding(16.dp), .size(36.dp)
colors = DatePickerDefaults.colors( .background(
dayContentColor = MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.onBackground,
RoundedCornerShape(18.dp)
)
.padding(start = 13.dp, top = 8.dp),
textStyle = TextStyle(color = MaterialTheme.colorScheme.background),
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = "Радиус",
textAlign = TextAlign.Center,
)
Spacer(modifier = Modifier.height(4.dp))
BasicTextField(
value = itemUiState.itemDetails.radius,
onValueChange = { onUpdate(itemUiState.itemDetails.copy(radius = it)) },
modifier = Modifier
.fillMaxWidth()
.size(36.dp)
.background(
MaterialTheme.colorScheme.onBackground,
RoundedCornerShape(18.dp)
)
.padding(start = 13.dp, top = 8.dp),
textStyle = TextStyle(color = MaterialTheme.colorScheme.background),
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = "Цвет",
textAlign = TextAlign.Center,
)
Spacer(modifier = Modifier.height(4.dp))
BasicTextField(
value = itemUiState.itemDetails.colorbike,
onValueChange = { onUpdate(itemUiState.itemDetails.copy(colorbike = it)) },
modifier = Modifier
.fillMaxWidth()
.size(36.dp)
.background(
MaterialTheme.colorScheme.onBackground,
RoundedCornerShape(18.dp)
)
.padding(start = 13.dp, top = 8.dp),
textStyle = TextStyle(color = MaterialTheme.colorScheme.background),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Done
) )
) )
// } Spacer(modifier = Modifier.height(4.dp))
val selectedDate = dateState.selectedDateMillis?.toLocalDate() Text(
if (selectedDate != null) { text = "Количество",
val resultDateTime = LocalDateTime.of(selectedDate, LocalTime.MIDNIGHT) textAlign = TextAlign.Center,
onUpdate(itemUiState.itemDetails.copy(dateTime = resultDateTime))
}
} else {
val dateState = rememberDatePickerState(
initialDisplayMode = DisplayMode.Input
) )
/* Surface( Spacer(modifier = Modifier.height(4.dp))
tonalElevation = 6.dp, BasicTextField(
color = MaterialTheme.colorScheme.primary value = itemUiState.itemDetails.maxCount.toString(),
) {*/ onValueChange = { newValue ->
val parsedMaxCount = newValue.toIntOrNull() ?: 0 // Преобразование в Int
onUpdate(itemUiState.itemDetails.copy(maxCount = parsedMaxCount))
},
modifier = Modifier
.fillMaxWidth()
.size(36.dp)
.background(
MaterialTheme.colorScheme.onBackground,
RoundedCornerShape(18.dp)
)
.padding(start = 13.dp, top = 8.dp),
textStyle = TextStyle(color = MaterialTheme.colorScheme.background),
)
Spacer(modifier = Modifier.height(4.dp))
if (itemUiState.itemDetails.dateTime != LocalDateTime.MIN) {
val selectedDateMillis =
itemUiState.itemDetails.dateTime.toInstant(ZoneOffset.UTC).toEpochMilli()
val dateState = rememberDatePickerState(
initialDisplayMode = DisplayMode.Input,
initialSelectedDateMillis = selectedDateMillis
)
/* Surface(
tonalElevation = 6.dp,
color = MaterialTheme.colorScheme.primary
) {*/
DatePicker( DatePicker(
state = dateState, state = dateState,
modifier = Modifier.padding(16.dp), modifier = Modifier.padding(16.dp),
@ -108,74 +244,55 @@ private fun ItemEdit(
dayContentColor = MaterialTheme.colorScheme.primary, dayContentColor = MaterialTheme.colorScheme.primary,
) )
) )
// } // }
val selectedDate = dateState.selectedDateMillis?.toLocalDate() val selectedDate = dateState.selectedDateMillis?.toLocalDate()
if (selectedDate != null) { if (selectedDate != null) {
val resultDateTime = LocalDateTime.of(selectedDate, LocalTime.MIDNIGHT) val resultDateTime = LocalDateTime.of(selectedDate, LocalTime.MIDNIGHT)
onUpdate(itemUiState.itemDetails.copy(dateTime = resultDateTime)) onUpdate(itemUiState.itemDetails.copy(dateTime = resultDateTime))
}
} else {
val dateState = rememberDatePickerState(
initialDisplayMode = DisplayMode.Input
)
/* Surface(
tonalElevation = 6.dp,
color = MaterialTheme.colorScheme.primary
) {*/
DatePicker(
state = dateState,
modifier = Modifier.padding(16.dp),
colors = DatePickerDefaults.colors(
dayContentColor = MaterialTheme.colorScheme.primary,
)
)
// }
val selectedDate = dateState.selectedDateMillis?.toLocalDate()
if (selectedDate != null) {
val resultDateTime = LocalDateTime.of(selectedDate, LocalTime.MIDNIGHT)
onUpdate(itemUiState.itemDetails.copy(dateTime = resultDateTime))
}
}
Button(
onClick = onClick,
enabled = itemUiState.isEntryValid,
shape = MaterialTheme.shapes.small,
modifier = Modifier.fillMaxWidth()
) {
Text(text = "Сохранить")
} }
}
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = itemUiState.itemDetails.weight,
label = { Text(text = "Вес") },
onValueChange = {
onUpdate(itemUiState.itemDetails.copy(weight = it))
},
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
textStyle = MaterialTheme.typography.bodyLarge.copy(
color = MaterialTheme.colorScheme.onSecondary
)
)
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = itemUiState.itemDetails.radius,
label = { Text(text = "R") },
onValueChange = {
onUpdate(itemUiState.itemDetails.copy(radius = it))
},
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
textStyle = MaterialTheme.typography.bodyLarge.copy(
color = MaterialTheme.colorScheme.onSecondary
)
)
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = itemUiState.itemDetails.colorbike,
label = { Text(text = "Цвет") },
onValueChange = {
onUpdate(itemUiState.itemDetails.copy(colorbike = it))
},
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Text),
textStyle = MaterialTheme.typography.bodyLarge.copy(
color = MaterialTheme.colorScheme.onSecondary
)
)
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = itemUiState.itemDetails.maxCount.toString(),
onValueChange = { newValue ->
val parsedMaxCount = newValue.toIntOrNull() ?: 0 // Преобразование в Int
onUpdate(itemUiState.itemDetails.copy(maxCount = parsedMaxCount))
},
label = { Text(text = "Количество") },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
textStyle = MaterialTheme.typography.bodyLarge.copy(
color = MaterialTheme.colorScheme.onSecondary
)
)
Button(
onClick = onClick,
enabled = itemUiState.isEntryValid,
shape = MaterialTheme.shapes.small,
modifier = Modifier.fillMaxWidth()
) {
Text(text = stringResource(R.string.Save_button))
} }
} }
} }
} }
private fun parseDate(dateString: MutableState<String>): Date? {
return try {
// Use SimpleDateFormat or any other method to parse the string into a Date object
// For example:
SimpleDateFormat("yyyy", Locale.getDefault()).parse(dateString.toString())
} catch (e: ParseException) {
// Handle parsing error
null
}
}

View File

@ -32,6 +32,24 @@
"maxCount": 5, "maxCount": 5,
"bikeId": 3, "bikeId": 3,
"id": 2 "id": 2
},
{
"id": 3,
"dateTime": 2005,
"weight": 12.5,
"radius": 14.5,
"colorbike": "Красный",
"maxCount": 15,
"bikeId": 5
},
{
"dateTime": 2023,
"weight": 15.5,
"radius": 14.5,
"colorbike": "Красный",
"maxCount": 10,
"bikeId": 4,
"id": 4
} }
], ],
"bikes": [ "bikes": [