Compare commits

..

5 Commits

Author SHA1 Message Date
487d228a9b add bookScreen 2025-11-28 19:51:36 +03:00
9b8cbedf63 add testIds 2025-11-28 16:02:01 +03:00
0cc27350bc add auth-code validation 2025-11-27 21:40:27 +03:00
7dc115052d add maincreen 2025-11-25 19:52:38 +03:00
25de07692b upload 2025-11-24 23:04:54 +03:00
18 changed files with 817 additions and 91 deletions

View File

@@ -0,0 +1,234 @@
package ru.myitschool.work.ui
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.RowScope
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.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ru.myitschool.work.R
import ru.myitschool.work.core.TestIds.Main
import ru.myitschool.work.ui.theme.Black
import ru.myitschool.work.ui.theme.Blue
import ru.myitschool.work.ui.theme.Gray
import ru.myitschool.work.ui.theme.LightBlue
import ru.myitschool.work.ui.theme.LightGray
import ru.myitschool.work.ui.theme.Typography
import ru.myitschool.work.ui.theme.White
@Composable
fun BaseText24(
text: String,
modifier: Modifier = Modifier,
color: Color = Black,
textAlign: TextAlign = TextAlign.Left
) {
Text(
text = text,
fontSize = 24.sp,
style = Typography.bodyLarge,
modifier = modifier,
color = color,
textAlign = textAlign
)
}
@Composable
fun BaseNoBackgroundButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
Button(
onClick = onClick,
modifier = modifier,
colors = ButtonDefaults.buttonColors(
containerColor = Color.Transparent,
contentColor = White,
disabledContainerColor = Color.Transparent,
disabledContentColor = White
)
) {
BaseText16(text = text, color = White)
}
}
@Composable
fun Logo() {
Image(
painter = painterResource(R.drawable.logo),
contentDescription = "Logo",
modifier = Modifier.padding(top = 40.dp, bottom = 60.dp)
)
}
@Composable
fun BaseText16(
text: String,
modifier: Modifier = Modifier,
color: Color = Black,
) {
Text(
text = text,
style = Typography.bodySmall,
fontSize = 16.sp,
color = color,
modifier = modifier
)
}
@Composable
fun BaseText12(
modifier: Modifier = Modifier,
text: String,
color: Color = Black,
) {
Text(
text = text,
style = Typography.bodySmall,
fontSize = 12.sp,
color = color,
modifier = modifier,
)
}
@Composable
fun BaseText14(
modifier: Modifier = Modifier,
text: String,
color: Color = Black,
) {
Text(
text = text,
style = Typography.bodySmall,
fontSize = 14.sp,
color = color,
modifier = modifier,
)
}
@Composable
fun BaseInputText(
placeholder: String= "",
modifier: Modifier = Modifier,
valueChange: (String) -> Unit,
value: String
) {
TextField(
value = value,
onValueChange = valueChange,
shape = RoundedCornerShape(16.dp),
placeholder = {
BaseText16(
text = placeholder,
color = Gray
)
},
textStyle = Typography.bodySmall.copy(fontSize = 16.sp),
colors = TextFieldDefaults.colors(
focusedContainerColor = LightBlue,
unfocusedContainerColor = LightBlue,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent,
errorIndicatorColor = Color.Transparent
),
singleLine = true,
modifier = modifier
)
}
@Composable
fun BaseText20(
text: String,
color: Color = Color.Unspecified,
style: TextStyle = Typography.bodySmall,
modifier: Modifier = Modifier.padding(7.dp),
textAlign: TextAlign = TextAlign.Unspecified
) {
Text(
text = text,
style = style,
fontSize = 20.sp,
modifier = modifier,
color = color,
textAlign = textAlign
)
}
@Composable
fun BaseButton(
enable: Boolean = true,
text: String,
btnColor: Color,
btnContentColor: Color,
onClick: () -> Unit,
icon: @Composable RowScope.() -> Unit = {},
modifier: Modifier = Modifier.fillMaxWidth()
) {
Button(
enabled = enable,
onClick = onClick,
colors = ButtonDefaults.buttonColors(
containerColor = btnColor,
contentColor = btnContentColor,
disabledContainerColor = LightGray,
disabledContentColor = Gray
),
modifier = modifier,
shape = RoundedCornerShape(16.dp),
) {
icon()
BaseText20(text = text)
}
}
@Composable
fun ErrorScreen() {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(horizontal = 20.dp, vertical = 40.dp)
) {
Spacer(modifier = Modifier.height(80.dp))
BaseText24(
text = "Ошибка загрузки данных",
textAlign = TextAlign.Center,
modifier = Modifier
.testTag(Main.ERROR)
.width(250.dp)
)
Spacer(modifier = Modifier.height(30.dp))
BaseButton(
modifier = Modifier.testTag(Main.REFRESH_BUTTON),
text = "Обновить",
btnColor = Blue,
btnContentColor = White,
onClick = {}
)
}
}

View File

@@ -3,4 +3,4 @@ package ru.myitschool.work.ui.nav
import kotlinx.serialization.Serializable
@Serializable
data object AuthScreenDestination: AppDestination
data object AuthScreenDestination: ru.myitschool.work.ui.nav.AppDestination

View File

@@ -3,4 +3,4 @@ package ru.myitschool.work.ui.nav
import kotlinx.serialization.Serializable
@Serializable
data object BookScreenDestination: AppDestination
data object BookScreenDestination: ru.myitschool.work.ui.nav.AppDestination

View File

@@ -3,4 +3,6 @@ package ru.myitschool.work.ui.nav
import kotlinx.serialization.Serializable
@Serializable
data object MainScreenDestination: AppDestination
data object MainScreenDestination: AppDestination {
val userData = ""
}

View File

@@ -15,6 +15,8 @@ import ru.myitschool.work.ui.nav.AuthScreenDestination
import ru.myitschool.work.ui.nav.BookScreenDestination
import ru.myitschool.work.ui.nav.MainScreenDestination
import ru.myitschool.work.ui.screen.auth.AuthScreen
import ru.myitschool.work.ui.screen.book.BookScreen
import ru.myitschool.work.ui.screen.main.MainScreen
@Composable
fun AppNavHost(
@@ -29,21 +31,18 @@ fun AppNavHost(
startDestination = AuthScreenDestination,
) {
composable<AuthScreenDestination> {
AuthScreen(navController = navController)
AuthScreen(
navController = navController)
}
composable<MainScreenDestination> {
Box(
contentAlignment = Alignment.Center
) {
Text(text = "Hello")
}
MainScreen(
navController = navController
)
}
composable<BookScreenDestination> {
Box(
contentAlignment = Alignment.Center
) {
Text(text = "Hello")
}
BookScreen(
navController = navController
)
}
}
}

View File

@@ -3,10 +3,12 @@ package ru.myitschool.work.ui.screen.auth
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
@@ -26,72 +28,148 @@ import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import ru.myitschool.work.R
import ru.myitschool.work.core.TestIds
import ru.myitschool.work.ui.BaseButton
import ru.myitschool.work.ui.BaseInputText
import ru.myitschool.work.ui.BaseText12
import ru.myitschool.work.ui.BaseText24
import ru.myitschool.work.ui.Logo
import ru.myitschool.work.ui.nav.MainScreenDestination
import ru.myitschool.work.ui.theme.Blue
import ru.myitschool.work.ui.theme.Red
import ru.myitschool.work.ui.theme.White
@Composable
fun AuthScreen(
viewModel: AuthViewModel = viewModel(),
navController: NavController
) {
val state by viewModel.uiState.collectAsState()
LaunchedEffect(Unit) {
viewModel.actionFlow.collect {
navController.navigate(MainScreenDestination)
}
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
.fillMaxHeight()
.width(200.dp)
.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
Logo()
BaseText24(
text = stringResource(R.string.auth_title),
style = MaterialTheme.typography.headlineSmall,
textAlign = TextAlign.Center
)
when (val currentState = state) {
is AuthState.Data -> Content(viewModel, currentState)
is AuthState.Loading -> {
CircularProgressIndicator(
modifier = Modifier.size(64.dp)
Column(
modifier = Modifier.padding(vertical = 20.dp)
) {
val textState by viewModel.textState.collectAsStateWithLifecycle()
val errorState by viewModel.errorState.collectAsStateWithLifecycle()
BaseInputText(
value = textState,
placeholder = stringResource(R.string.auth_label),
modifier = Modifier
.testTag(TestIds.Auth.CODE_INPUT)
.fillMaxWidth(),
valueChange = {viewModel.updateText(it)}
)
if (errorState) {
BaseText12(
text = "Недействительный код сотрудника",
color = Red,
modifier = Modifier
.testTag(TestIds.Auth.ERROR)
.padding(
start = 10.dp,
top = 5.dp,
bottom = 0.dp
)
.fillMaxWidth()
)
}
}
}
}
@Composable
private fun Content(
viewModel: AuthViewModel,
state: AuthState.Data
) {
var inputText by remember { mutableStateOf("") }
Spacer(modifier = Modifier.size(16.dp))
TextField(
modifier = Modifier.testTag(TestIds.Auth.CODE_INPUT).fillMaxWidth(),
value = inputText,
onValueChange = {
inputText = it
viewModel.onIntent(AuthIntent.TextInput(it))
},
label = { Text(stringResource(R.string.auth_label)) }
val isButtonEnabled by viewModel.isButtonEnabled.collectAsStateWithLifecycle()
BaseButton(
text = stringResource(R.string.auth_sign_in),
onClick = { navController.navigate(MainScreenDestination)},
btnColor = Blue,
enable = isButtonEnabled,
btnContentColor = White,
modifier = Modifier
.testTag(TestIds.Auth.SIGN_BUTTON)
.fillMaxWidth()
)
Spacer(modifier = Modifier.size(16.dp))
Button(
modifier = Modifier.testTag(TestIds.Auth.SIGN_BUTTON).fillMaxWidth(),
onClick = {
viewModel.onIntent(AuthIntent.Send(inputText))
},
enabled = true
) {
Text(stringResource(R.string.auth_sign_in))
}
}
//@Composable
//fun AuthScreen(
// viewModel: AuthViewModel = viewModel(),
// navController: NavController
//) {
// val state by viewModel.uiState.collectAsState()
//
// LaunchedEffect(Unit) {
// viewModel.actionFlow.collect {
// navController.navigate(MainScreenDestination)
// }
// }
//
// Column(
// modifier = Modifier
// .fillMaxSize()
// .padding(all = 24.dp),
// horizontalAlignment = Alignment.CenterHorizontally,
// verticalArrangement = Arrangement.Center
// ) {
// Text(
// text = stringResource(R.string.auth_title),
// style = MaterialTheme.typography.headlineSmall,
// textAlign = TextAlign.Center
// )
// when (val currentState = state) {
// is AuthState.Data -> Content(viewModel, currentState)
// is AuthState.Loading -> {
// CircularProgressIndicator(
// modifier = Modifier.size(64.dp)
// )
// }
// }
// }
//}
//
//@Composable
//private fun Content(
// viewModel: AuthViewModel,
// state: AuthState.Data
//) {
// var inputText by remember { mutableStateOf("") }
// Spacer(modifier = Modifier.size(16.dp))
// TextField(
// modifier = Modifier.testTag(TestIds.Auth.CODE_INPUT).fillMaxWidth(),
// value = inputText,
// onValueChange = {
// inputText = it
// viewModel.onIntent(AuthIntent.TextInput(it))
// },
// label = { Text(stringResource(R.string.auth_label)) }
// )
// Spacer(modifier = Modifier.size(16.dp))
// Button(
// modifier = Modifier.testTag(TestIds.Auth.SIGN_BUTTON).fillMaxWidth(),
// onClick = {
// viewModel.onIntent(AuthIntent.Send(inputText))
// },
// enabled = true
// ) {
// Text(stringResource(R.string.auth_sign_in))
// }
//}

View File

@@ -1,43 +1,66 @@
package ru.myitschool.work.ui.screen.auth
import androidx.compose.runtime.mutableIntStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import ru.myitschool.work.data.repo.AuthRepository
import ru.myitschool.work.domain.auth.CheckAndSaveAuthCodeUseCase
class AuthViewModel : ViewModel() {
private val checkAndSaveAuthCodeUseCase by lazy { CheckAndSaveAuthCodeUseCase(AuthRepository) }
private val _uiState = MutableStateFlow<AuthState>(AuthState.Data)
val uiState: StateFlow<AuthState> = _uiState.asStateFlow()
// private val checkAndSaveAuthCodeUseCase by lazy { CheckAndSaveAuthCodeUseCase(AuthRepository) }
// private val _uiState = MutableStateFlow<AuthState>(AuthState.Data)
// val uiState: StateFlow<AuthState> = _uiState.asStateFlow()
//
// private val _actionFlow: MutableSharedFlow<Unit> = MutableSharedFlow()
// val actionFlow: SharedFlow<Unit> = _actionFlow
//
// fun onIntent(intent: AuthIntent) {
// when (intent) {
// is AuthIntent.Send -> {
// viewModelScope.launch(Dispatchers.Default) {
// _uiState.update { AuthState.Loading }
// checkAndSaveAuthCodeUseCase.invoke("9999").fold(
// onSuccess = {
// _actionFlow.emit(Unit)
// },
// onFailure = { error ->
// error.printStackTrace()
// _actionFlow.emit(Unit)
// }
// )
// }
// }
// is AuthIntent.TextInput -> Unit
// }
// }
private val _actionFlow: MutableSharedFlow<Unit> = MutableSharedFlow()
val actionFlow: SharedFlow<Unit> = _actionFlow
private val _textState = MutableStateFlow("")
val textState: StateFlow<String> = _textState.asStateFlow()
fun onIntent(intent: AuthIntent) {
when (intent) {
is AuthIntent.Send -> {
viewModelScope.launch(Dispatchers.Default) {
_uiState.update { AuthState.Loading }
checkAndSaveAuthCodeUseCase.invoke("9999").fold(
onSuccess = {
_actionFlow.emit(Unit)
},
onFailure = { error ->
error.printStackTrace()
_actionFlow.emit(Unit)
private val _errorState = MutableStateFlow(false)
val errorState: StateFlow<Boolean> = _errorState.asStateFlow()
fun updateText(newText: String) {
_textState.value = newText
_errorState.value = false
}
val isButtonEnabled: StateFlow<Boolean> =
_textState.map { it.length == 4 && it.matches(Regex("^[a-zA-Z0-9]*\$"))}
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = false
)
}
}
is AuthIntent.TextInput -> Unit
}
}
}

View File

@@ -0,0 +1,129 @@
package ru.myitschool.work.ui.screen.book
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import ru.myitschool.work.R
import ru.myitschool.work.core.TestIds.Main
import ru.myitschool.work.ui.BaseButton
import ru.myitschool.work.ui.BaseNoBackgroundButton
import ru.myitschool.work.ui.BaseText16
import ru.myitschool.work.ui.BaseText20
import ru.myitschool.work.ui.BaseText24
import ru.myitschool.work.ui.nav.BookScreenDestination
import ru.myitschool.work.ui.theme.Black
import ru.myitschool.work.ui.theme.Blue
import ru.myitschool.work.ui.theme.Gray
import ru.myitschool.work.ui.theme.LightGray
import ru.myitschool.work.ui.theme.MontserratFontFamily
import ru.myitschool.work.ui.theme.White
@Composable
fun BookScreen(
navController: NavController
) {
Column(
) {
Row(
) {
BaseText24(
text = "Новая встреча"
)
BaseNoBackgroundButton(
text = "Назад",
onClick = {}
)
}
Column(
) {
BaseText16(
text = "Доступные даты"
)
BookDateList()
BaseText16(
text = "Выберите место встречи"
)
BookPlaceList()
BaseButton(
text = "Бронировать",
btnColor = Blue,
btnContentColor = White,
onClick = { navController.navigate(BookScreenDestination)},
modifier = Modifier
.testTag(Main.ADD_BUTTON)
.padding(horizontal = 10.dp, vertical = 15.dp)
.fillMaxWidth(),
icon = {Image(
painter = painterResource(R.drawable.add_icon),
contentDescription = "plus Icon"
)}
)
}
}
}
@Composable
fun BookPlaceList() {
BookPlaceListElement()
}
@Composable
fun BookPlaceListElement() {
}
@Composable
fun BookDateList() {
BookDateListElement()
BookDateListElement()
BookDateListElement()
BookDateListElement()
BookDateListElement()
BookDateListElement()
BookDateListElement()
}
@Composable
fun BookDateListElement() {
Button(
border = BorderStroke(1.dp, Black),
onClick = {},
modifier = Modifier
.width(60.dp)
.padding(0.dp),
colors = ButtonColors(
contentColor = Black,
containerColor = Color.Transparent,
disabledContentColor = Black,
disabledContainerColor = Color.Transparent),
shape = RoundedCornerShape(16.dp)
) {
BaseText16(text = "16.06")
}
}

View File

@@ -0,0 +1,186 @@
package ru.myitschool.work.ui.screen.main
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
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.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import ru.myitschool.work.R
import ru.myitschool.work.core.TestIds.Main
import ru.myitschool.work.ui.BaseButton
import ru.myitschool.work.ui.BaseNoBackgroundButton
import ru.myitschool.work.ui.BaseText14
import ru.myitschool.work.ui.BaseText16
import ru.myitschool.work.ui.BaseText20
import ru.myitschool.work.ui.BaseText24
import ru.myitschool.work.ui.ErrorScreen
import ru.myitschool.work.ui.nav.BookScreenDestination
import ru.myitschool.work.ui.theme.Black
import ru.myitschool.work.ui.theme.Blue
import ru.myitschool.work.ui.theme.LightGray
import ru.myitschool.work.ui.theme.Typography
import ru.myitschool.work.ui.theme.White
@Composable
fun MainScreen(
navController: NavController
) {
Column (
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.background(LightGray)
.fillMaxSize()
.width(400.dp)
) {
val dateError = false
if(!dateError) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.clip(RoundedCornerShape(bottomStart = 16.dp, bottomEnd = 16.dp))
.background(Blue)
.fillMaxWidth()
.padding(10.dp)
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth()
) {
BaseNoBackgroundButton(
text = "Обновить",
onClick = { },
modifier = Modifier.testTag(Main.REFRESH_BUTTON)
)
BaseNoBackgroundButton(
text = "Выйти",
onClick = { },
modifier = Modifier.testTag(Main.LOGOUT_BUTTON)
)
}
Image(
painter = painterResource(R.drawable.avatar),
contentDescription = "User avatar",
modifier = Modifier
.testTag(Main.PROFILE_IMAGE)
.padding(20.dp)
)
BaseText20(
text = "Артемий Артемиев Иванович",
color = White,
textAlign = TextAlign.Center,
modifier = Modifier
.testTag(Main.PROFILE_NAME)
.width(250.dp),
style = Typography.bodyLarge
)
Spacer(modifier = Modifier.height(20.dp))
}
Column(
verticalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
.fillMaxSize()
.padding(20.dp)
.clip(RoundedCornerShape(16.dp))
.background(White)
) {
Column(
modifier = Modifier.fillMaxWidth()
) {
Text(
text = "Ваши забронированные места",
style = Typography.bodyMedium,
color = Black,
fontSize = 16.sp,
modifier = Modifier.padding(
horizontal = 10.dp,
vertical = 20.dp
)
)
BookList()
}
BaseButton(
text = "Бронировать",
btnColor = Blue,
btnContentColor = White,
onClick = { navController.navigate(BookScreenDestination)},
modifier = Modifier
.testTag(Main.ADD_BUTTON)
.padding(horizontal = 10.dp, vertical = 15.dp)
.fillMaxWidth(),
icon = {Image(
painter = painterResource(R.drawable.add_icon),
contentDescription = "plus Icon"
)}
)
}
}
else {
ErrorScreen()
}
}
}
val bookListData = listOf(
"Конгресс Холл",
"Конгресс Холл",
"Конгресс Холл"
)
@Composable
fun BookList() {
Column(
modifier = Modifier.padding(horizontal = 20.dp)
) {
for ((index, book) in bookListData.withIndex()) {
BookListElement(index)
}
}
}
@Composable
fun BookListElement(index: Int) {
Row(
modifier = Modifier
.testTag(Main.getIdItemByPosition(index))
.fillMaxWidth()
.padding(vertical = 20.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
BaseText14(
text = "Конгресс Холл",
modifier = Modifier.testTag(Main.ITEM_PLACE)
)
BaseText14(
text = "16.02.3026",
modifier = Modifier.testTag(Main.ITEM_DATE)
)
}
}

View File

@@ -9,3 +9,17 @@ val Pink80 = Color(0xFFEFB8C8)
val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)
val Blue = Color(0xFF004BFF)
val Gray = Color(0xFF777777)
val LightBlue = Color(0xFFF2EFFF)
val White = Color(0xFFFFFFFF)
val Red = Color(0xFFFF4D4D)
val LightGray = Color(0xFFF2F1F7)
val Black = Color(0xFF000000)

View File

@@ -2,19 +2,34 @@ package ru.myitschool.work.ui.theme
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import ru.myitschool.work.R
// Set of Material typography styles to start with
val Typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
val MontserratFontFamily = FontFamily(
Font(R.font.montserrat_bold, FontWeight.Bold),
Font(R.font.montserrat_medium, FontWeight.Medium),
Font(R.font.montserrat_semibold, weight = FontWeight.SemiBold)
)
val Typography = Typography(
bodySmall = TextStyle(
fontFamily = MontserratFontFamily,
fontWeight = FontWeight.Medium,
),
bodyMedium = TextStyle(
fontFamily = MontserratFontFamily,
fontWeight = FontWeight.SemiBold,
),
bodyLarge = TextStyle(
fontFamily = MontserratFontFamily,
fontWeight = FontWeight.Bold,
),
/* Other default text styles to override
titleLarge = TextStyle(
fontFamily = FontFamily.Default,

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="17dp"
android:height="17dp"
android:viewportWidth="17"
android:viewportHeight="17">
<path
android:strokeWidth="1"
android:pathData="M8.296,0.5C8.503,0.5 8.656,0.565 8.786,0.695C8.916,0.826 8.981,0.977 8.98,1.183V7.61H15.405C15.615,7.61 15.767,7.676 15.896,7.805C16.026,7.934 16.09,8.086 16.09,8.294C16.089,8.503 16.024,8.657 15.894,8.788C15.767,8.917 15.616,8.981 15.407,8.98H8.98V15.405C8.98,15.615 8.914,15.767 8.785,15.896C8.656,16.026 8.504,16.09 8.296,16.09C8.087,16.089 7.934,16.024 7.805,15.894C7.676,15.766 7.61,15.615 7.61,15.405V8.98H1.185C0.975,8.98 0.823,8.915 0.695,8.786C0.566,8.656 0.5,8.503 0.5,8.294C0.5,8.086 0.565,7.935 0.694,7.806C0.825,7.675 0.978,7.61 1.185,7.61H7.61V1.185C7.61,0.975 7.676,0.824 7.805,0.695C7.934,0.566 8.087,0.501 8.296,0.5Z"
android:fillColor="#ffffff"
android:strokeColor="#ffffff"/>
</vector>

View File

@@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="100dp"
android:height="100dp"
android:viewportWidth="100"
android:viewportHeight="100">
<path
android:pathData="M50,50m-48.5,0a48.5,48.5 0,1 1,97 0a48.5,48.5 0,1 1,-97 0"
android:strokeWidth="3"
android:fillColor="#AEC3FF"
android:strokeColor="#ffffff"/>
<path
android:pathData="M61.99,54.17C64.58,54.17 66.67,56.26 66.67,58.85V60.05C66.67,61.91 66.01,63.71 64.8,65.13C61.53,68.95 56.55,70.83 50,70.83C43.45,70.83 38.48,68.95 35.21,65.13C34,63.71 33.34,61.91 33.34,60.05V58.85C33.34,56.26 35.44,54.17 38.03,54.17H61.99ZM61.99,57.29H38.03C37.16,57.29 36.47,57.99 36.47,58.85V60.05C36.47,61.17 36.86,62.25 37.59,63.1C40.2,66.16 44.3,67.71 50,67.71C55.71,67.71 59.8,66.16 62.42,63.1C63.15,62.25 63.55,61.17 63.55,60.05V58.85C63.55,57.99 62.85,57.29 61.99,57.29ZM50,29.18C55.75,29.18 60.42,33.84 60.42,39.59C60.42,45.35 55.75,50.01 50,50.01C44.25,50.01 39.58,45.35 39.58,39.59C39.58,33.84 44.25,29.18 50,29.18ZM50,32.3C45.97,32.3 42.71,35.57 42.71,39.59C42.71,43.62 45.97,46.88 50,46.88C54.03,46.88 57.29,43.62 57.29,39.59C57.29,35.57 54.03,32.3 50,32.3Z"
android:fillColor="#ffffff"/>
</vector>

View File

@@ -0,0 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="53dp"
android:height="99dp"
android:viewportWidth="53"
android:viewportHeight="99">
<path
android:pathData="M33.501,13.467V35.047H52.507C52.507,24.867 44.587,16.26 33.501,13.467Z"
android:fillColor="#004BFF"/>
<path
android:pathData="M0.267,61.92C0.267,72.08 8.187,80.713 19.274,83.507V61.92H0.267Z"
android:fillColor="#004BFF"/>
<path
android:pathData="M52.781,61.92C52.507,46.767 36.027,41.173 28.594,39.6C25.087,38.84 18.814,36.933 19.007,33.713V13.44C8.621,16.053 -0.293,24.873 0.007,35.473C1.714,53.393 19.207,55.613 29.341,58.88C32.581,60.153 33.861,61.78 33.781,63.333V83.513C44.041,80.993 52.901,72.16 52.781,61.92Z"
android:fillColor="#004BFF"/>
<path
android:pathData="M26.374,85.92C22.941,85.92 20.047,84.867 19.234,83.54L26.374,98.3L33.754,83.513C32.714,84.813 29.821,85.92 26.374,85.92Z"
android:fillColor="#004BFF"/>
<path
android:pathData="M26.661,13.467C29.821,13.467 32.467,12.407 32.467,10.8V2.62C32.467,1.32 29.801,0 26.661,0C23.221,0 20.601,1.053 20.601,2.667V10.813C20.574,12.14 23.221,13.467 26.661,13.467Z"
android:fillColor="#004BFF"/>
</vector>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,7 +1,7 @@
<resources>
<string name="app_name">Work</string>
<string name="title_activity_root">RootActivity</string>
<string name="auth_title">Привет! Введи код для авторизации</string>
<string name="auth_title">Введите код для авторизации</string>
<string name="auth_label">Код</string>
<string name="auth_sign_in">Войти</string>
</resources>