diff --git a/app/src/main/java/ru/myitschool/work/data/repo/MeetingsRepository.kt b/app/src/main/java/ru/myitschool/work/data/repo/MeetingsRepository.kt new file mode 100644 index 0000000..270a3ec --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/data/repo/MeetingsRepository.kt @@ -0,0 +1,9 @@ +package ru.myitschool.work.data.repo + +object MeetingsRepository { + private var roomCache: String? = null + + fun getRoom(): String? { + return roomCache + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/domain/auth/CheckCodeFormatUseCase.kt b/app/src/main/java/ru/myitschool/work/domain/auth/CheckCodeFormatUseCase.kt deleted file mode 100644 index 1bb8ea4..0000000 --- a/app/src/main/java/ru/myitschool/work/domain/auth/CheckCodeFormatUseCase.kt +++ /dev/null @@ -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()) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/domain/meetings/GetRoomUseCase.kt b/app/src/main/java/ru/myitschool/work/domain/meetings/GetRoomUseCase.kt new file mode 100644 index 0000000..13d1e0d --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/domain/meetings/GetRoomUseCase.kt @@ -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() + } +} diff --git a/app/src/main/java/ru/myitschool/work/ui/custom/component/CustomButton.kt b/app/src/main/java/ru/myitschool/work/ui/custom/component/CustomButton.kt new file mode 100644 index 0000000..ddb7b86 --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/ui/custom/component/CustomButton.kt @@ -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 + ) +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/nav/MeetingsScreenDestination.kt b/app/src/main/java/ru/myitschool/work/ui/nav/MeetingsScreenDestination.kt new file mode 100644 index 0000000..a61a2db --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/ui/nav/MeetingsScreenDestination.kt @@ -0,0 +1,6 @@ +package ru.myitschool.work.ui.nav + +import kotlinx.serialization.Serializable + +@Serializable +data object MeetingsScreenDestination: AppDestination diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/NavigationGraph.kt b/app/src/main/java/ru/myitschool/work/ui/screen/NavigationGraph.kt index bcd283f..0afffd8 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/NavigationGraph.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/NavigationGraph.kt @@ -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 { BookScreen(navController = navController) } + composable { + MeetingsScreen() + } } } } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthScreen.kt b/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthScreen.kt index 89d01b3..703c25f 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthScreen.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthScreen.kt @@ -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)) diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/book/BookScreen.kt b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookScreen.kt index 60842f3..1e8f7b4 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/book/BookScreen.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookScreen.kt @@ -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, diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/main/MainScreen.kt b/app/src/main/java/ru/myitschool/work/ui/screen/main/MainScreen.kt index 0b22914..6ae6d18 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/main/MainScreen.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/main/MainScreen.kt @@ -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") diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingIntent.kt b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingIntent.kt index 5903cc4..83c58b3 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingIntent.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingIntent.kt @@ -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 diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsScreen.kt b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsScreen.kt index ac26a83..1b001af 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsScreen.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsScreen.kt @@ -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 +) { + } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsState.kt b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsState.kt index bd7f381..fc79e03 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsState.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsState.kt @@ -9,22 +9,11 @@ sealed interface MeetingsState { val error: String ): MeetingsState data class Data( - val name: String, - val photoUrl: String, val books: PersistentList, - val items: PersistentList ): MeetingsState { data class Book( val date: String, - val place: String, - ) - data class Item( - val date: String, - val places: PersistentList, - ) - data class Place( - val id: String, - val name: String, ) } -} \ No newline at end of file +} + diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsViewModel.kt index 4587b9d..ffdbda5 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsViewModel.kt @@ -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.Loading) + val uiState: StateFlow = _uiState.asStateFlow() + + private val _actionFlow: MutableSharedFlow = MutableSharedFlow() + val actionFlow: SharedFlow = _actionFlow + + } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/theme/Color.kt b/app/src/main/java/ru/myitschool/work/ui/theme/Color.kt index 22226f4..92c0a81 100644 --- a/app/src/main/java/ru/myitschool/work/ui/theme/Color.kt +++ b/app/src/main/java/ru/myitschool/work/ui/theme/Color.kt @@ -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) \ No newline at end of file +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))) diff --git a/app/src/main/java/ru/myitschool/work/ui/theme/Font.kt b/app/src/main/java/ru/myitschool/work/ui/theme/Font.kt new file mode 100644 index 0000000..aae57bf --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/ui/theme/Font.kt @@ -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, + ) +) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/theme/Theme.kt b/app/src/main/java/ru/myitschool/work/ui/theme/Theme.kt index d9cc58f..7e2b73d 100644 --- a/app/src/main/java/ru/myitschool/work/ui/theme/Theme.kt +++ b/app/src/main/java/ru/myitschool/work/ui/theme/Theme.kt @@ -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 { diff --git a/app/src/main/java/ru/myitschool/work/ui/theme/Type.kt b/app/src/main/java/ru/myitschool/work/ui/theme/Type.kt index 61b2923..4081ad5 100644 --- a/app/src/main/java/ru/myitschool/work/ui/theme/Type.kt +++ b/app/src/main/java/ru/myitschool/work/ui/theme/Type.kt @@ -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 ) - */ ) \ No newline at end of file diff --git a/app/src/main/res/drawable/no_accounts.png b/app/src/main/res/drawable/no_accounts.png new file mode 100644 index 0000000..f42249a Binary files /dev/null and b/app/src/main/res/drawable/no_accounts.png differ diff --git a/app/src/main/res/drawable/not_auth.xml b/app/src/main/res/drawable/not_auth.xml new file mode 100644 index 0000000..361e4f0 --- /dev/null +++ b/app/src/main/res/drawable/not_auth.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/not_wifi.png b/app/src/main/res/drawable/not_wifi.png new file mode 100644 index 0000000..ec9d53a Binary files /dev/null and b/app/src/main/res/drawable/not_wifi.png differ diff --git a/app/src/main/res/font/merriweather_120pt_bold.ttf b/app/src/main/res/font/merriweather_120pt_bold.ttf new file mode 100644 index 0000000..69416ac Binary files /dev/null and b/app/src/main/res/font/merriweather_120pt_bold.ttf differ diff --git a/app/src/main/res/font/merriweather_120pt_medium.ttf b/app/src/main/res/font/merriweather_120pt_medium.ttf new file mode 100644 index 0000000..3a88e1b Binary files /dev/null and b/app/src/main/res/font/merriweather_120pt_medium.ttf differ diff --git a/app/src/main/res/font/roboto_serif_120pt_regular.ttf b/app/src/main/res/font/roboto_serif_120pt_regular.ttf new file mode 100644 index 0000000..d5dbfa6 Binary files /dev/null and b/app/src/main/res/font/roboto_serif_120pt_regular.ttf differ diff --git a/local.properties b/local.properties index 6530068..dcf330e 100644 --- a/local.properties +++ b/local.properties @@ -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