Initial commit

This commit is contained in:
2025-10-29 09:55:11 +03:00
parent ac5d12ac53
commit 86f7ee35ce
16 changed files with 24 additions and 138 deletions

View File

@@ -1,5 +1,10 @@
package ru.myitschool.work.core
// ДАННЫЙ КЛАСС ПРИ ТЕСТИРОВАНИИ БУДЕТ ВОЗВРАЩЁН В ОРИГИНАЛЬНОЕ ЗНАЧЕНИЕ
// Используйте ссылки только из переменных этого класса
// Можете изменить хост, но для тестирование он будет подменён тестовым сервером
object Constants {
const val HOST = "http://10.0.2.2:8080"
const val USER_URL = "/user"

View File

@@ -1,26 +1,14 @@
package ru.myitschool.work.data
import ru.myitschool.work.data.source.NetworkDataSource
import ru.myitschool.work.domain.entities.BookingEntity
import ru.myitschool.work.domain.entities.UserEntity
object AppRepository {
suspend fun loadData(): Result<UserEntity> {
return NetworkDataSource.getUser().map { dto ->
UserEntity(
name = dto.name,
bookingList = dto.booking.map { bookingDto ->
BookingEntity(
roomName = bookingDto.room,
time = bookingDto.time
)
}
)
}
suspend fun loadData(): UserEntity {
TODO("заверши написание кода")
}
suspend fun addBook(room: String, time: String): Result<Unit> {
return NetworkDataSource.addBook(room, time)
suspend fun addBook(room: String, time: String) {
// TODO: заверши написание кода
}
}

View File

@@ -1,10 +0,0 @@
package ru.myitschool.work.data.dto
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class ErrorDto(
@SerialName("error")
val error: String,
)

View File

@@ -1,20 +0,0 @@
package ru.myitschool.work.data.dto
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class UserDto(
@SerialName("name")
val name: String,
@SerialName("booking")
val booking: List<BookingDto>
) {
@Serializable
data class BookingDto(
@SerialName("room")
val room: String,
@SerialName("time")
val time: String,
)
}

View File

@@ -1,71 +0,0 @@
package ru.myitschool.work.data.source
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.engine.cio.CIO
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.request.forms.FormPart
import io.ktor.client.request.forms.MultiPartFormDataContent
import io.ktor.client.request.forms.formData
import io.ktor.client.request.get
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.http.HttpStatusCode
import io.ktor.serialization.kotlinx.json.json
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json
import ru.myitschool.work.core.Constants
import ru.myitschool.work.data.dto.ErrorDto
import ru.myitschool.work.data.dto.UserDto
object NetworkDataSource {
private val client by lazy {
HttpClient(CIO) {
install(ContentNegotiation) {
json(
Json {
isLenient = true
ignoreUnknownKeys = true
explicitNulls = true
encodeDefaults = true
}
)
}
}
}
suspend fun getUser(): Result<UserDto> = withContext(Dispatchers.IO) {
return@withContext runCatching {
val response = client.get(Constants.FULL_USER_URL)
if (response.status == HttpStatusCode.OK) {
response.body<UserDto>()
} else {
error(response.body<ErrorDto>().error)
}
}
}
suspend fun addBook(
room: String,
time: String,
): Result<Unit> = withContext(Dispatchers.IO) {
return@withContext runCatching {
val response = client.post(Constants.FULL_BOOK_URL) {
setBody(
MultiPartFormDataContent(
formData(
FormPart("room", room),
FormPart("time", time),
)
)
)
}
if (response.status == HttpStatusCode.OK) {
Unit
} else {
error(response.body<ErrorDto>().error)
}
}
}
}

View File

@@ -9,9 +9,11 @@ class AddBookUseCase(
room: String,
time: String,
): Result<Unit> {
return repository.addBook(
room = room,
time = time,
return Result.success(
repository.addBook(
room = room,
time = time,
)
)
}
}

View File

@@ -7,6 +7,6 @@ class GetUserDataUseCase(
private val repository: AppRepository
) {
suspend operator fun invoke(): Result<UserEntity> {
return repository.loadData()
return Result.success(repository.loadData())
}
}

View File

@@ -1,5 +1,6 @@
package ru.myitschool.work.domain.entities
// ДАННЫЙ КЛАСС ЗАПРЕЩЕНО МОДИЦИФИРОВАТЬ! ПРИ ТЕСТИРОВАНИИ ОН БУДЕТ ВОЗВРАЩЁН В ОРИГИНАЛЬНОЕ ЗНАЧЕНИЕ
data class BookingEntity(
val roomName: String,
val time: String,

View File

@@ -1,5 +1,6 @@
package ru.myitschool.work.domain.entities
// ДАННЫЙ КЛАСС ЗАПРЕЩЕНО МОДИЦИФИРОВАТЬ! ПРИ ТЕСТИРОВАНИИ ОН БУДЕТ ВОЗВРАЩЁН В ОРИГИНАЛЬНОЕ ЗНАЧЕНИЕ
data class UserEntity(
val name: String,
val bookingList: List<BookingEntity>

View File

@@ -32,6 +32,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import ru.myitschool.work.ui.theme.WorkTheme
// ДАННЫЙ КЛАСС ЗАПРЕЩЕНО МОДИЦИФИРОВАТЬ! ПРИ ТЕСТИРОВАНИИ ОН БУДЕТ ВОЗВРАЩЁН В ОРИГИНАЛЬНОЕ ЗНАЧЕНИЕ
class RootActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@@ -1,5 +1,6 @@
package ru.myitschool.work.ui.root
// ДАННЫЙ КЛАСС ЗАПРЕЩЕНО МОДИЦИФИРОВАТЬ! ПРИ ТЕСТИРОВАНИИ ОН БУДЕТ ВОЗВРАЩЁН В ОРИГИНАЛЬНОЕ ЗНАЧЕНИЕ
sealed interface RootIntent {
data object LoadData: RootIntent
data class AddBook(

View File

@@ -2,6 +2,7 @@ package ru.myitschool.work.ui.root
import ru.myitschool.work.domain.entities.UserEntity
// ДАННЫЙ КЛАСС ЗАПРЕЩЕНО МОДИЦИФИРОВАТЬ! ПРИ ТЕСТИРОВАНИИ ОН БУДЕТ ВОЗВРАЩЁН В ОРИГИНАЛЬНОЕ ЗНАЧЕНИЕ
sealed interface RootState {
data object NotLoaded: RootState
data object Loading: RootState

View File

@@ -11,6 +11,7 @@ import ru.myitschool.work.data.AppRepository
import ru.myitschool.work.domain.AddBookUseCase
import ru.myitschool.work.domain.GetUserDataUseCase
// ДАННЫЙ КЛАСС ЗАПРЕЩЕНО МОДИЦИФИРОВАТЬ! ПРИ ТЕСТИРОВАНИИ ОН БУДЕТ ВОЗВРАЩЁН В ОРИГИНАЛЬНОЕ ЗНАЧЕНИЕ
class RootViewModel : ViewModel() {
private val getUserDataUseCase by lazy {
GetUserDataUseCase(

View File

@@ -2,6 +2,7 @@ package ru.myitschool.work.ui.theme
import androidx.compose.ui.graphics.Color
// ДАННЫЙ КЛАСС ЗАПРЕЩЕНО МОДИЦИФИРОВАТЬ! ПРИ ТЕСТИРОВАНИИ ОН БУДЕТ ВОЗВРАЩЁН В ОРИГИНАЛЬНОЕ ЗНАЧЕНИЕ
val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)

View File

@@ -10,6 +10,7 @@ import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
// ДАННЫЙ КЛАСС ЗАПРЕЩЕНО МОДИЦИФИРОВАТЬ! ПРИ ТЕСТИРОВАНИИ ОН БУДЕТ ВОЗВРАЩЁН В ОРИГИНАЛЬНОЕ ЗНАЧЕНИЕ
private val DarkColorScheme = darkColorScheme(
primary = Purple80,
secondary = PurpleGrey80,

View File

@@ -6,7 +6,7 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
// Set of Material typography styles to start with
// ДАННЫЙ КЛАСС ЗАПРЕЩЕНО МОДИЦИФИРОВАТЬ! ПРИ ТЕСТИРОВАНИИ ОН БУДЕТ ВОЗВРАЩЁН В ОРИГИНАЛЬНОЕ ЗНАЧЕНИЕ
val Typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
@@ -15,20 +15,4 @@ val Typography = Typography(
lineHeight = 24.sp,
letterSpacing = 0.5.sp
)
/* Other default text styles to override
titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
),
labelSmall = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Medium,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
*/
)