main #6

Closed
student-20690 wants to merge 20 commits from (deleted):main into main
6 changed files with 49 additions and 38 deletions
Showing only changes of commit 77f27e52eb - Show all commits

View File

@@ -1,7 +1,7 @@
package ru.myitschool.work.core
object Constants {
const val HOST = "http://10.230.214.96:8080"
const val HOST = "http://192.168.1.39:8080"
const val AUTH_URL = "/auth"
const val INFO_URL = "/info"
const val BOOKING_URL = "/booking"

View File

@@ -1,5 +1,6 @@
package ru.myitschool.work.data.source
import android.annotation.SuppressLint
import android.util.Log
import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
@@ -151,20 +152,20 @@ object NetworkDataSource {
}
@Serializable
private data class CreateBookingBody(val date: String, val placeID: Long)
private data class CreateBookingBody(val date: String, val placeId: Long)
suspend fun createBooking(code: String, date: LocalDate, placeId: Long): Result<Boolean> = withContext(Dispatchers.IO) {
return@withContext runCatching {
// Формируем тело запроса
val requestBody = CreateBookingBody(date.toString(), placeId)
val response = client.post(getUrl(code, Constants.BOOKING_URL)) { // Используем ту же константу BOOKING_URL
val response = client.post(getUrl(code, Constants.BOOK_URL)) {
contentType(ContentType.Application.Json)
setBody(requestBody)
}
when (response.status) {
HttpStatusCode.OK -> true
HttpStatusCode.Created -> true
else -> {
val errorBody = response.bodyAsText()
error(if (errorBody.isNotBlank()) App.context.getString(R.string.error_booking, errorBody) else App.context.getString(R.string.error_booking_default))

View File

@@ -1,19 +1,34 @@
package ru.myitschool.work.ui.screen.book
import androidx.compose.foundation.layout.*
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.selection.selectable
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.RadioButton
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.Tab
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import ru.myitschool.work.core.TestIds
import ru.myitschool.work.data.entity.Place
import java.time.LocalDate
import java.time.format.DateTimeFormatter
@Composable
fun BookScreen(
@@ -23,23 +38,19 @@ fun BookScreen(
val viewModel: BookViewModel = viewModel()
val uiState by viewModel.uiState.collectAsState()
// Обработка действий
val event = viewModel.actionFlow.collectAsState(initial = null)
LaunchedEffect(event.value) {
when (event.value) {
is BookAction.BookSuccess -> {
LaunchedEffect(viewModel.actionFlow) {
viewModel.actionFlow.collect { action ->
if (action is BookAction.BookSuccess) {
onBookSuccess()
}
else -> {}
}
}
// Загрузка начальных данных
LaunchedEffect(Unit) {
viewModel.onIntent(BookIntent.LoadData)
}
when (uiState) {
when (val state = uiState) {
is BookState.Loading -> {
Box(
modifier = Modifier.fillMaxSize(),
@@ -51,7 +62,7 @@ fun BookScreen(
is BookState.Data -> {
BookContentScreen(
uiState = uiState as BookState.Data,
uiState = state,
onSelectDate = { date -> viewModel.onIntent(BookIntent.SelectDate(date)) },
onSelectPlace = { place -> viewModel.onIntent(BookIntent.SelectPlace(place)) },
onBook = { viewModel.onIntent(BookIntent.BookPlace) },
@@ -71,13 +82,10 @@ fun BookContentScreen(
onBack: () -> Unit,
onRefresh: () -> Unit
) {
// Сортировка дат по порядку
val sortedDates = uiState.dates.sorted()
// Фильтрация дат, для которых есть доступные места
val availableDates = sortedDates.filter { date -> uiState.places[date]?.isNotEmpty() == true }
Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
// Вкладки для выбора дат
if (availableDates.isNotEmpty()) {
ScrollableTabRow(
selectedTabIndex = availableDates.indexOf(uiState.selectedDate),
@@ -100,7 +108,6 @@ fun BookContentScreen(
Spacer(modifier = Modifier.height(16.dp))
// Список мест для выбранной даты
val placesForDate = uiState.selectedDate?.let { uiState.places[it] } ?: emptyList()
if (placesForDate.isNotEmpty()) {
@@ -131,7 +138,6 @@ fun BookContentScreen(
}
}
// пустой список (все забронировано)
if (availableDates.isEmpty() && !uiState.isError) {
Text(
text = "Всё забронировано",
@@ -139,7 +145,6 @@ fun BookContentScreen(
)
}
// ошибка
if (uiState.isError) {
Text(
text = uiState.errorMessage ?: "Ошибка загрузки",
@@ -157,7 +162,6 @@ fun BookContentScreen(
Spacer(modifier = Modifier.weight(1f))
// Кнопки: Забронировать и Назад
if (!uiState.isError && placesForDate.isNotEmpty()) {
Button(
onClick = onBook,

View File

@@ -1,5 +1,6 @@
package ru.myitschool.work.ui.screen.book
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
@@ -121,11 +122,22 @@ class BookViewModel : ViewModel() {
viewModelScope.launch(Dispatchers.IO) {
createBookingUseCase (date, placeId).fold(
onSuccess = {
Log.d("AnnaKonda", "method is calling")
_actionFlow.emit(BookAction.BookSuccess)
},
onFailure = { error ->
Log.d("AnnaKonda", "ERROR method is calling")
error.printStackTrace()
_actionFlow.emit(BookAction.ShowError(error.message ?: App.context.getString(R.string.error_booking_default)))
_uiState.update { currentState ->
if (currentState is BookState.Data) {
currentState.copy(
isError = true
)
} else {
currentState
}
}
// _actionFlow.emit(BookAction.ShowError(error.message ?: App.context.getString(R.string.error_booking_default)))
}
)
}

View File

@@ -13,6 +13,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import coil3.compose.AsyncImage
import ru.myitschool.work.core.TestIds
@@ -25,7 +26,7 @@ import ru.myitschool.work.ui.nav.BookScreenDestination
fun MainScreen(
navController: NavController,
) {
val viewModel = MainViewModel()
val viewModel: MainViewModel = viewModel()
// Состояния
val event = viewModel.actionFlow.collectAsState(initial = null)
// Функция загрузки данных

View File

@@ -12,14 +12,10 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import ru.myitschool.work.data.repo.AuthRepository
import ru.myitschool.work.data.repo.MainRepository
import ru.myitschool.work.domain.auth.CheckAndSaveAuthCodeUseCase
import ru.myitschool.work.domain.main.GetUserDataUseCase
import ru.myitschool.work.ui.screen.auth.AuthAction
import ru.myitschool.work.ui.screen.auth.AuthIntent
import ru.myitschool.work.ui.screen.auth.AuthState
class MainViewModel : ViewModel() {
private val repository by lazy{ MainRepository() }
private val repository by lazy { MainRepository() }
private val getUserDataUseCase by lazy { GetUserDataUseCase(repository) }
private val _uiState = MutableStateFlow<MainState>(MainState.Loading)
@@ -28,15 +24,12 @@ class MainViewModel : ViewModel() {
private val _actionFlow: MutableSharedFlow<MainAction> = MutableSharedFlow()
val actionFlow: SharedFlow<MainAction> = _actionFlow
init {
loadData()
}
fun onIntent(intent: MainIntent) {
when (intent) {
is MainIntent.LoadData -> {
is MainIntent.LoadData -> {
loadData()
}
is MainIntent.LogOut -> {
viewModelScope.launch(Dispatchers.IO) {
_uiState.update { MainState.Data(null) }
@@ -46,7 +39,7 @@ class MainViewModel : ViewModel() {
}
}
fun loadData() {
private fun loadData() {
viewModelScope.launch(Dispatchers.IO) {
_uiState.update { MainState.Loading }