checkpoint 0 #5

Open
student-e-klyukin wants to merge 15 commits from WindWin-org/NTO-2026-Android-TeamTask-Template:main into main
24 changed files with 337 additions and 54 deletions
Showing only changes of commit 3c2d359a01 - Show all commits

View File

@ -0,0 +1,9 @@
package ru.myitschool.work.data.repo
object MeetingsRepository {
private var roomCache: String? = null
fun getRoom(): String? {
return roomCache
}
}

View File

@ -1,12 +0,0 @@
package ru.myitschool.work.domain.auth
class CheckCodeFormatUseCase {
operator fun invoke(
text: String
): Boolean {
return text.length == 4 && text.all { char ->
char.isLetterOrDigit() &&
((char in 'A'..'Z') || (char >= 'a' && char <= 'z') || char.isDigit())
}
}
}

View File

@ -0,0 +1,11 @@
package ru.myitschool.work.domain.meetings
import ru.myitschool.work.data.repo.MeetingsRepository
class GetRoomUseCase (
private val repository: MeetingsRepository
) {
suspend operator fun invoke(): String? {
return repository.getRoom()
}
}

View File

@ -0,0 +1,64 @@
package ru.myitschool.work.ui.custom.component
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.RoundRect
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import ru.myitschool.work.ui.theme.gray_gradient
import ru.myitschool.work.ui.theme.orange_gradient
@Composable
fun CustomButon(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
round : Dp = 10.dp,
content: @Composable RowScope.() -> Unit,
) {
Box(
modifier = modifier
.clickable { onClick() }
.background(if (enabled) orange_gradient else gray_gradient, RoundedCornerShape(round))
) {
Row(
modifier = Modifier
.defaultMinSize(
minWidth = ButtonDefaults.MinWidth,
minHeight = ButtonDefaults.MinHeight,
)
.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
content = content,
)
}
}
@Composable
fun RoundCustomButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
content: @Composable RowScope.() -> Unit,
) {
CustomButon(
onClick, modifier, enabled, content = content,
round = 50.dp
)
}

View File

@ -0,0 +1,6 @@
package ru.myitschool.work.ui.nav
import kotlinx.serialization.Serializable
@Serializable
data object MeetingsScreenDestination: AppDestination

View File

@ -20,9 +20,11 @@ import ru.myitschool.work.ui.nav.AppDestination
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.nav.MeetingsScreenDestination
import ru.myitschool.work.ui.screen.auth.AuthScreen
import ru.myitschool.work.ui.screen.book.BookScreen
import ru.myitschool.work.ui.screen.main.MainScreen
import ru.myitschool.work.ui.screen.meetings.MeetingsScreen
@Composable
fun AppNavHost(
@ -37,6 +39,7 @@ fun AppNavHost(
} else {
MainScreenDestination
}
// destination = MainScreenDestination
}
if (destination != null) {
NavHost(
@ -55,6 +58,9 @@ fun AppNavHost(
composable<BookScreenDestination> {
BookScreen(navController = navController)
}
composable<MeetingsScreenDestination> {
MeetingsScreen()
}
}
}
}

View File

@ -31,6 +31,7 @@ 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.custom.component.CustomButon
@Composable
fun AuthScreen(
@ -102,7 +103,7 @@ private fun Content(
label = { Text(stringResource(R.string.auth_password)) }
)
Spacer(modifier = Modifier.size(16.dp))
Button(
CustomButon(
modifier = Modifier.testTag(TestIds.Auth.SIGN_BUTTON).fillMaxWidth(),
onClick = {
viewModel.onIntent(AuthIntent.Send(inputTextLogin, inputTextPassword))

View File

@ -141,6 +141,22 @@ private fun ErrorState(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
when (state.error) {
"No auth" -> {
Image(
painter = painterResource(R.drawable.no_accounts),
null,
Modifier.size(100.dp)
)
}
"Not internet" -> {
Image(
painter = painterResource(R.drawable.not_wifi),
null,
Modifier.size(100.dp)
)
}
}
Text(
modifier = Modifier.testTag(TestIds.Book.ERROR),
text = state.error,

View File

@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
@ -30,9 +29,13 @@ 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.graphics.ImageBitmap
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@ -43,6 +46,8 @@ import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import ru.myitschool.work.R
import ru.myitschool.work.core.TestIds
import ru.myitschool.work.ui.custom.component.CustomButon
import ru.myitschool.work.ui.custom.component.RoundCustomButton
@Composable
fun MainScreen(
@ -113,14 +118,30 @@ private fun ErrorState(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
when (state.error) {
"No auth" -> {
Image(
painter = painterResource(R.drawable.no_accounts),
null,
Modifier.size(100.dp)
)
}
"Not internet" -> {
Image(
painter = painterResource(R.drawable.not_wifi),
null,
Modifier.size(100.dp)
)
}
}
Text(
modifier = Modifier.testTag(TestIds.Main.ERROR),
text = state.error,
style = MaterialTheme.typography.headlineSmall,
color = Color.Black,
color = Color.Red
)
Spacer(modifier = Modifier.size(16.dp))
Button(
RoundCustomButton(
modifier = Modifier.testTag(TestIds.Main.REFRESH_BUTTON).fillMaxWidth(),
onClick = {
println("!!!!!!!! refresh on click error")

View File

@ -1,8 +1,17 @@
package ru.myitschool.work.ui.screen.meetings
sealed interface MeetingIntent {
/**
* Обнавление страницы
*/
data object Refresh: MeetingIntent
/**
* Выход
*/
data object Logout: MeetingIntent
/**
* Бронирование
*/
data class Add(
val date: String,
val placeId: String

View File

@ -1,4 +1,62 @@
package ru.myitschool.work.ui.screen.meetings
class MeetingsScreen {
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.viewmodel.compose.viewModel
import ru.myitschool.work.ui.screen.book.BookAction
import ru.myitschool.work.ui.screen.book.BookViewModel
import ru.myitschool.work.ui.screen.main.MainResult
@Composable
fun MeetingsScreen(
viewModel: MeetingsViewModel = viewModel()
) {
val state by viewModel.uiState.collectAsState()
Column(
Modifier
.fillMaxSize()
) {
when (val currentState = state) {
is MeetingsState.Data -> MeetingsData(currentState)
is MeetingsState.Empty -> MeetingsEmpty(currentState)
is MeetingsState.Error -> TODO()
is MeetingsState.Loading -> TODO()
}
}
}
@Composable
fun MeetingsData(
state: MeetingsState.Data
) {
}
@Composable
fun MeetingsEmpty(
state: MeetingsState.Empty
) {
}
@Composable
fun MeetingsError(
state: MeetingsState.Error
) {
}
@Composable
fun MeetingsLoading(
state: MeetingsState.Loading
) {
}

View File

@ -9,22 +9,11 @@ sealed interface MeetingsState {
val error: String
): MeetingsState
data class Data(
val name: String,
val photoUrl: String,
val books: PersistentList<Book>,
val items: PersistentList<Item>
): MeetingsState {
data class Book(
val date: String,
val place: String,
)
data class Item(
val date: String,
val places: PersistentList<Place>,
)
data class Place(
val id: String,
val name: String,
)
}
}

View File

@ -1,4 +1,18 @@
package ru.myitschool.work.ui.screen.meetings
class MeetingsViewModel {
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
class MeetingsViewModel : ViewModel() {
private val _uiState = MutableStateFlow<MeetingsState>(MeetingsState.Loading)
val uiState: StateFlow<MeetingsState> = _uiState.asStateFlow()
private val _actionFlow: MutableSharedFlow<MeetingsAction> = MutableSharedFlow()
val actionFlow: SharedFlow<MeetingsAction> = _actionFlow
}

View File

@ -1,11 +1,20 @@
package ru.myitschool.work.ui.theme
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)
val day_primary = Color(0xFFffa500)
val day_secondary = Color(0xFFffd700)
val day_tertiary = Color(0xFFffbe00)
val day_text = Color(0xFF003366)
val day_background = Color(0xFFf0f0f0)
val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)
val night_primary = Color(0xFFff8c00)
val night_secondary = Color(0xFFff7300)
val night_tertiary = Color(0xFFff5a00)
val night_text = Color(0xFFffe4b5)
val night_background = Color(0xFF121212)
val orange_gradient = Brush.linearGradient(listOf(day_primary, night_primary))
val gray_gradient = Brush.linearGradient(listOf(Color(0xFFc4c7cf), Color(0xFF828897)))

View File

@ -0,0 +1,26 @@
package ru.myitschool.work.ui.theme
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import ru.myitschool.work.R
val subtitle = FontFamily(
Font(
R.font.merriweather_120pt_medium,
weight = FontWeight.Medium,
)
)
val title = FontFamily(
Font(
R.font.merriweather_120pt_bold,
weight = FontWeight.Bold
)
)
val normal = FontFamily(
Font(
R.font.roboto_serif_120pt_regular,
)
)

View File

@ -11,15 +11,21 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
private val DarkColorScheme = darkColorScheme(
primary = Purple80,
secondary = PurpleGrey80,
tertiary = Pink80
primary = night_primary,
secondary = night_secondary,
tertiary = night_tertiary,
background = night_background,
onBackground = night_text,
onSurface = night_text,
)
private val LightColorScheme = lightColorScheme(
primary = Purple40,
secondary = PurpleGrey40,
tertiary = Pink40
primary = day_primary,
secondary = day_secondary,
tertiary = day_tertiary,
background = day_background,
onBackground = day_text,
onSurface = day_text
/* Other default colors to override
background = Color(0xFFFFFBFE),
@ -36,7 +42,7 @@ private val LightColorScheme = lightColorScheme(
fun WorkTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = true,
dynamicColor: Boolean = false,
content: @Composable () -> Unit
) {
val colorScheme = when {

View File

@ -9,26 +9,24 @@ import androidx.compose.ui.unit.sp
// Set of Material typography styles to start with
val Typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontFamily = subtitle,
fontWeight = FontWeight.Medium,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
)
/* Other default text styles to override
),
titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontFamily = title,
fontWeight = FontWeight.Bold,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
),
labelSmall = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Medium,
fontFamily = normal,
fontWeight = FontWeight.Normal,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
*/
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4,5 +4,5 @@
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Tue Feb 24 18:06:36 MSK 2026
#Wed Feb 25 10:24:12 MSK 2026
sdk.dir=C\:\\Users\\Samsung\\AppData\\Local\\Android\\Sdk