From 4287921be342165b79d69a55bffacdd2c318fb64 Mon Sep 17 00:00:00 2001 From: Artem Gruzdev Date: Wed, 12 Jul 2023 15:51:14 +0600 Subject: [PATCH 1/3] [+] add calendar to main screen --- .../buildSrc/src/main/kotlin/Dependencies.kt | 8 + composeApp/build.gradle.kts | 3 + .../effective/office/elevator/App.android.kt | 1 + .../office/elevator/components/Calendar.kt | 163 ++++++++++++++++++ .../elevator/components/ModalCalendar.kt | 100 +++++++++++ .../office/elevator/ui/main/MainScreen.kt | 20 ++- .../ui/main/components/BookingInformation.kt | 5 +- .../ui/main/components/DateSelection.kt | 11 +- .../elevator/ui/main/store/MainStore.kt | 13 +- .../ui/main/store/MainStoreFactory.kt | 28 +++ .../office/elevator/utils/GetCurrentDate.kt | 10 ++ .../resources/MR/base/strings_ru.xml | 4 + .../commonMain/resources/MR/en/strings_en.xml | 3 + 13 files changed, 359 insertions(+), 10 deletions(-) create mode 100644 composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/Calendar.kt create mode 100644 composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/ModalCalendar.kt create mode 100644 composeApp/src/commonMain/kotlin/band/effective/office/elevator/utils/GetCurrentDate.kt diff --git a/buildSrc/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/buildSrc/src/main/kotlin/Dependencies.kt index 17fd2396..f0cf0dfe 100644 --- a/buildSrc/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/buildSrc/src/main/kotlin/Dependencies.kt @@ -25,6 +25,7 @@ object Dependencies { const val logback = "1.2.11" const val shadow = "7.1.2" const val moko = "0.23.0" + const val calendar = "1.0.4" } object Ktor { @@ -127,4 +128,11 @@ object Dependencies { object Moko{ const val resourcesCompose = "dev.icerock.moko:resources-compose:${Versions.moko}" } + + object Calendar{ + const val composeBasic = "io.github.epicarchitect:calendar-compose-basis:${Versions.calendar}" + const val composeRanges = "io.github.epicarchitect:calendar-compose-ranges:${Versions.calendar}" + const val composePager = "io.github.epicarchitect:calendar-compose-pager:${Versions.calendar}" + const val composeDatePicker = "io.github.epicarchitect:calendar-compose-datepicker:${Versions.calendar}" + } } \ No newline at end of file diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 65f9fad9..2247c76d 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -46,6 +46,7 @@ kotlin { implementation(compose.runtime) implementation(compose.foundation) implementation(compose.material) + implementation(compose.material3) implementation(compose.materialIconsExtended) implementation(Dependencies.ImageLoader.imageLoader) implementation(Dependencies.Napier.napier) @@ -72,6 +73,8 @@ kotlin { //Moko api(Dependencies.Moko.resourcesCompose) + + implementation(Dependencies.Calendar.composeDatePicker) } } diff --git a/composeApp/src/androidMain/kotlin/band/effective/office/elevator/App.android.kt b/composeApp/src/androidMain/kotlin/band/effective/office/elevator/App.android.kt index b92246ab..7d315a6b 100644 --- a/composeApp/src/androidMain/kotlin/band/effective/office/elevator/App.android.kt +++ b/composeApp/src/androidMain/kotlin/band/effective/office/elevator/App.android.kt @@ -7,6 +7,7 @@ import androidx.activity.compose.setContent import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview import androidx.core.os.BuildCompat.PrereleaseSdkCheck +import band.effective.office.elevator.components.Calendar import band.effective.office.elevator.di.androidModuleDI import band.effective.office.elevator.di.appModuleDI import band.effective.office.elevator.domain.AppActivityLifecycleObserver diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/Calendar.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/Calendar.kt new file mode 100644 index 00000000..4b4f0756 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/Calendar.kt @@ -0,0 +1,163 @@ +package band.effective.office.elevator.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.ArrowForward +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment.Companion.CenterVertically +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import epicarchitect.calendar.compose.basis.BasisDayOfMonthContent +import epicarchitect.calendar.compose.basis.BasisDayOfWeekContent +import epicarchitect.calendar.compose.basis.EpicMonth +import epicarchitect.calendar.compose.basis.config.LocalBasisEpicCalendarConfig +import epicarchitect.calendar.compose.basis.config.rememberMutableBasisEpicCalendarConfig +import epicarchitect.calendar.compose.basis.contains +import epicarchitect.calendar.compose.basis.localized +import epicarchitect.calendar.compose.basis.state.LocalBasisEpicCalendarState +import epicarchitect.calendar.compose.datepicker.EpicDatePicker +import epicarchitect.calendar.compose.datepicker.config.rememberEpicDatePickerConfig +import epicarchitect.calendar.compose.datepicker.state.EpicDatePickerState +import epicarchitect.calendar.compose.datepicker.state.LocalEpicDatePickerState +import epicarchitect.calendar.compose.datepicker.state.rememberEpicDatePickerState +import epicarchitect.calendar.compose.pager.config.rememberEpicCalendarPagerConfig +import epicarchitect.calendar.compose.pager.state.EpicCalendarPagerState +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import kotlinx.datetime.DayOfWeek +import kotlinx.datetime.LocalDate + +@Composable +fun Calendar(state: EpicDatePickerState) { + + val coroutineScope = rememberCoroutineScope() + + val pagerState = state.pagerState + + Column { + CalendarTitle( + selectedDate = if (state.selectedDates.isEmpty()) + pagerState.currentMonth.month.name + else + stringFormat(state.selectedDates.first()), + onClickNextMonth = { scrollMonth(coroutineScope, pagerState, 1) }, + onClickPreviousMonth = { scrollMonth(coroutineScope, pagerState, -1) } + ) + Spacer(modifier = Modifier.height(16.dp)) + EpicDatePicker( + state = state, + dayOfMonthContent = CustomDayOfMonthContent, + dayOfWeekContent = CustomDayOfWeekContent + ) + } +} + +@Composable +fun CalendarTitle( + onClickPreviousMonth: () -> Unit, + onClickNextMonth: () -> Unit, + selectedDate: String +) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = CenterVertically + ) { + Icon( + imageVector = Icons.Default.ArrowBack, + contentDescription = null, + modifier = Modifier + .size(32.dp) + .clickable { onClickPreviousMonth() }, + tint = Color.Black + ) + Text( + text = selectedDate, + fontSize = 20.sp, + color = Color.Black + ) + Icon( + imageVector = Icons.Default.ArrowForward, + contentDescription = null, + modifier = Modifier + .size(32.dp) + .clickable { onClickNextMonth() }, + tint = Color.Black + ) + } +} + +private fun scrollMonth( + coroutineScope: CoroutineScope, + pagerState: EpicCalendarPagerState, + amount: Int +) { + coroutineScope.launch { + pagerState.scrollMonths(amount) + } +} + +private fun stringFormat(date: LocalDate) = + "${date.month.name}, ${date.dayOfMonth}".lowercase() + +private val CustomDayOfWeekContent: BasisDayOfWeekContent = { dayOfWeek -> + val config = LocalBasisEpicCalendarConfig.current + Text( + text = dayOfWeek.localized(), + textAlign = TextAlign.Center, + color = config.contentColor, + fontSize = 20.sp, + maxLines = 1 + ) +} + +private val CustomDayOfMonthContent: BasisDayOfMonthContent = { date -> + val basisState = LocalBasisEpicCalendarState.current!! + val pickerState = LocalEpicDatePickerState.current!! + val selectedDays = pickerState.selectedDates + val selectionMode = pickerState.selectionMode + + val isSelected = remember(selectionMode, selectedDays, date) { + when (selectionMode) { + is EpicDatePickerState.SelectionMode.Range -> { + if (selectedDays.isEmpty()) false + else date in selectedDays.min()..selectedDays.max() + } + + is EpicDatePickerState.SelectionMode.Single -> date in selectedDays + } + } + + Text( + modifier = Modifier.alpha( + if (date in basisState.currentMonth) 1.0f + else 0.5f + ), + text = date.dayOfMonth.toString(), + textAlign = TextAlign.Center, + fontSize = 20.sp, + maxLines = 1, + color = if (isSelected) pickerState.config.selectionContentColor + else pickerState.config.pagerConfig.basisConfig.contentColor + ) +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/ModalCalendar.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/ModalCalendar.kt new file mode 100644 index 00000000..9298c78b --- /dev/null +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/ModalCalendar.kt @@ -0,0 +1,100 @@ +package band.effective.office.elevator.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +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.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Button +import androidx.compose.material.ButtonDefaults +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import band.effective.office.elevator.MainRes +import dev.icerock.moko.resources.StringResource +import dev.icerock.moko.resources.compose.stringResource +import epicarchitect.calendar.compose.basis.EpicMonth +import epicarchitect.calendar.compose.basis.config.rememberMutableBasisEpicCalendarConfig +import epicarchitect.calendar.compose.datepicker.config.rememberEpicDatePickerConfig +import epicarchitect.calendar.compose.datepicker.state.rememberEpicDatePickerState +import epicarchitect.calendar.compose.pager.config.rememberEpicCalendarPagerConfig +import kotlinx.datetime.LocalDate + +@Composable +fun ModalCalendar( + currentDate: LocalDate, + onClickOk: (LocalDate?) -> Unit, + onClickCansel: () -> Unit, + modifier: Modifier = Modifier +) { + val calendarConfig = rememberMutableBasisEpicCalendarConfig( + contentColor = Color.Black + ) + + val state = rememberEpicDatePickerState( + config = rememberEpicDatePickerConfig( + pagerConfig = rememberEpicCalendarPagerConfig( + basisConfig = calendarConfig + ), + selectionContentColor = MaterialTheme.colors.onPrimary, + selectionContainerColor = MaterialTheme.colors.secondaryVariant, + ), + initialMonth = EpicMonth(year = currentDate.year, month = currentDate.month), + selectedDates = listOf(currentDate) + ) + + Column( + modifier = modifier + .background(Color.White, shape = RoundedCornerShape(16.dp)) + .padding(horizontal = 16.dp, vertical = 24.dp) + ){ + Calendar(state = state) + Spacer(modifier = Modifier.height(24.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.End + ) { + ButtonAction( + onClick = onClickCansel, + buttonText = MainRes.strings.cansel + ) + Spacer(modifier = Modifier.width(14.dp)) + ButtonAction( + onClick = { onClickOk(state.selectedDates.firstOrNull()) }, + buttonText = MainRes.strings.ok + ) + } + } +} + +@Composable +private fun ButtonAction( + onClick: () -> Unit, + buttonText: StringResource +) { + Button( + onClick = onClick, + colors = ButtonDefaults.buttonColors( + backgroundColor = Color.White, + contentColor = Color.Black + ), + elevation = ButtonDefaults.elevation(0.dp, 0.dp, 0.dp, 0.dp) + ) { + Text( + text = stringResource(buttonText), + color = Color.Black, + fontSize = 16.sp + ) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/MainScreen.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/MainScreen.kt index e4c8eabf..ac3e04bd 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/MainScreen.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/MainScreen.kt @@ -23,7 +23,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import band.effective.office.elevator.MainRes -import band.effective.office.elevator.components.ElevatorButton +import band.effective.office.elevator.components.ModalCalendar import band.effective.office.elevator.components.TitlePage import band.effective.office.elevator.successGreen import band.effective.office.elevator.ui.main.components.BookingInformation @@ -42,6 +42,7 @@ fun MainScreen(component: MainComponent) { var isErrorMessageVisible by remember { mutableStateOf(false) } var isSuccessMessageVisible by remember { mutableStateOf(false) } var errorMessage by remember { mutableStateOf(MainRes.strings.something_went_wrong) } + var showModalCalendar by remember { mutableStateOf(false) } LaunchedEffect(component) { component.label.collect { label -> @@ -59,6 +60,8 @@ fun MainScreen(component: MainComponent) { isSuccessMessageVisible = false } MainStore.Label.ShowOptions -> {} + MainStore.Label.OpenCalendar -> showModalCalendar = true + MainStore.Label.CloseCalendar -> showModalCalendar = false } } } @@ -73,8 +76,17 @@ fun MainScreen(component: MainComponent) { reservedSeats = state.reservedSeats, onClickBook = { component.onOutput(MainComponent.Output.OpenBookingScreen) }, onClickShowOptions = { component.onEvent(MainStore.Intent.OnClickShowOption) }, - onClickShowMap = { component.onOutput(MainComponent.Output.OpenMap) } + onClickShowMap = { component.onOutput(MainComponent.Output.OpenMap) }, + onClickOpenCalendar = { component.onEvent(MainStore.Intent.OnClickOpenCalendar) } ) + if (showModalCalendar) { + ModalCalendar( + modifier = Modifier.align(Alignment.Center), + onClickCansel = { component.onEvent(MainStore.Intent.OnClickCloseCalendar) }, + onClickOk = { component.onEvent(MainStore.Intent.OnClickApplyDate(it)) }, + currentDate = state.currentDate + ) + } SnackBarErrorMessage( modifier = Modifier.align(Alignment.BottomCenter), isVisible = isErrorMessageVisible, @@ -115,6 +127,7 @@ fun MainScreenContent( onClickBook: () -> Unit, onClickShowMap: () -> Unit, onClickShowOptions: () -> Unit, + onClickOpenCalendar: () -> Unit ) { Column( modifier = Modifier.fillMaxSize() @@ -143,7 +156,8 @@ fun MainScreenContent( reservedSeats = reservedSeats, onClickBook = onClickBook, onClickShowMap = onClickShowMap, - onClickShowOptions = onClickShowOptions + onClickShowOptions = onClickShowOptions, + onClickOpenCalendar = onClickOpenCalendar ) } } diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/BookingInformation.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/BookingInformation.kt index de1537cd..efbd0a93 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/BookingInformation.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/BookingInformation.kt @@ -17,14 +17,15 @@ fun BookingInformation( reservedSeats: List, onClickBook: () -> Unit, onClickShowMap: () -> Unit, - onClickShowOptions: () -> Unit + onClickShowOptions: () -> Unit, + onClickOpenCalendar: () -> Unit ) { Column( modifier = Modifier .fillMaxSize() ) { Spacer(modifier = Modifier.height(24.dp)) - DateSelection() + DateSelection(onClickOpenCalendar = onClickOpenCalendar) Spacer(modifier = Modifier.height(24.dp)) SeatsReservation( reservedSeats = reservedSeats, diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/DateSelection.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/DateSelection.kt index 1f825c62..f2bc505f 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/DateSelection.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/DateSelection.kt @@ -1,6 +1,7 @@ package band.effective.office.elevator.ui.main.components import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -18,7 +19,7 @@ import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource @Composable -fun DateSelection() { +fun DateSelection(onClickOpenCalendar: () -> Unit) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceAround @@ -28,13 +29,15 @@ fun DateSelection() { fontSize = 15.sp, color = Color.Black ) - CalendarTitle() + CalendarTitle(onClickOpenCalendar = onClickOpenCalendar) } } @Composable -fun CalendarTitle() { - Row { +fun CalendarTitle(onClickOpenCalendar: () -> Unit) { + Row ( + modifier = Modifier.clickable { onClickOpenCalendar() } + ) { Image( painter = painterResource(MainRes.images.material_calendar_ic), contentDescription = null diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStore.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStore.kt index 126e53ad..fc74743b 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStore.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStore.kt @@ -4,6 +4,7 @@ import band.effective.office.elevator.ui.models.ElevatorState import band.effective.office.elevator.ui.models.ReservedSeat import com.arkivanov.mvikotlin.core.store.Store import dev.icerock.moko.resources.StringResource +import kotlinx.datetime.LocalDate interface MainStore : Store { @@ -11,6 +12,12 @@ interface MainStore : Store object OnClickCallElevator : Intent object OnClickShowOption : Intent + + object OnClickOpenCalendar : Intent + + object OnClickCloseCalendar : Intent + + data class OnClickApplyDate(val date: LocalDate?) : Intent } sealed interface Label { @@ -19,11 +26,15 @@ interface MainStore : Store object ShowOptions : Label + object CloseCalendar : Label + + object OpenCalendar : Label } data class State( val reservedSeats: List, - val elevatorState: ElevatorState + val elevatorState: ElevatorState, + val currentDate: LocalDate ) data class ErrorState(val message: StringResource) diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStoreFactory.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStoreFactory.kt index 10ed4ba4..3096b782 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStoreFactory.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStoreFactory.kt @@ -5,6 +5,7 @@ import band.effective.office.elevator.data.ApiResponse import band.effective.office.elevator.domain.OfficeElevatorRepository import band.effective.office.elevator.ui.models.ElevatorState import band.effective.office.elevator.ui.models.ReservedSeat +import band.effective.office.elevator.utils.getCurrentDate import com.arkivanov.mvikotlin.core.store.Reducer import com.arkivanov.mvikotlin.core.store.Store import com.arkivanov.mvikotlin.core.store.StoreFactory @@ -13,6 +14,10 @@ import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.format import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import kotlinx.datetime.Clock +import kotlinx.datetime.LocalDate +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toLocalDateTime import org.koin.core.component.KoinComponent import org.koin.core.component.inject @@ -44,6 +49,7 @@ internal class MainStoreFactory( bookingTime = "12:00 - 14:00" ), ), + currentDate = getCurrentDate() ), executorFactory = ::ExecutorImpl, reducer = ReducerImpl @@ -52,6 +58,8 @@ internal class MainStoreFactory( private sealed interface Msg { data class UpdateElevatorState(val elevatorState: ElevatorState) : Msg data class UpdateSeatsReservation(val reservedSeats: List) : Msg + + data class UpdateCurrentDate(val date: LocalDate?) : Msg } private inner class ExecutorImpl : @@ -67,6 +75,22 @@ internal class MainStoreFactory( publish(MainStore.Label.ShowOptions) } } + MainStore.Intent.OnClickCloseCalendar -> { + scope.launch { + publish(MainStore.Label.CloseCalendar) + } + } + MainStore.Intent.OnClickOpenCalendar -> { + scope.launch { + publish(MainStore.Label.OpenCalendar) + } + } + is MainStore.Intent.OnClickApplyDate -> { + scope.launch { + dispatch(Msg.UpdateCurrentDate(intent.date)) + publish(MainStore.Label.CloseCalendar) + } + } } } @@ -116,6 +140,10 @@ internal class MainStoreFactory( when (message) { is Msg.UpdateElevatorState -> copy(elevatorState = message.elevatorState) is Msg.UpdateSeatsReservation -> copy(reservedSeats = message.reservedSeats) + is Msg.UpdateCurrentDate -> { + if (message.date == null) this + else copy(currentDate = message.date) + } } } } diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/utils/GetCurrentDate.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/utils/GetCurrentDate.kt new file mode 100644 index 00000000..accaf60b --- /dev/null +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/utils/GetCurrentDate.kt @@ -0,0 +1,10 @@ +package band.effective.office.elevator.utils + +import kotlinx.datetime.Clock +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toLocalDateTime + + +// returns the date at the current time +fun getCurrentDate(timeZone: TimeZone = TimeZone.currentSystemDefault()) = + Clock.System.now().toLocalDateTime(timeZone).date \ No newline at end of file diff --git a/composeApp/src/commonMain/resources/MR/base/strings_ru.xml b/composeApp/src/commonMain/resources/MR/base/strings_ru.xml index d6161090..94e9afc4 100644 --- a/composeApp/src/commonMain/resources/MR/base/strings_ru.xml +++ b/composeApp/src/commonMain/resources/MR/base/strings_ru.xml @@ -17,6 +17,10 @@ Забронировать место Ваши ближайшие брони У вас пока нет бронирований + + Отмена + Ок + Профиль Главная diff --git a/composeApp/src/commonMain/resources/MR/en/strings_en.xml b/composeApp/src/commonMain/resources/MR/en/strings_en.xml index 12d489c9..ff68b71d 100644 --- a/composeApp/src/commonMain/resources/MR/en/strings_en.xml +++ b/composeApp/src/commonMain/resources/MR/en/strings_en.xml @@ -10,6 +10,9 @@ Your upcoming bookings You dont have any bookings yet + Cansel + Ok + Profile Main -- GitLab From f8117c3e94ae601e74318da25d2f783507af1895 Mon Sep 17 00:00:00 2001 From: Artem Gruzdev Date: Thu, 13 Jul 2023 16:36:03 +0600 Subject: [PATCH 2/3] [+] add switching seat reservation --- .../office/elevator/components/Calendar.kt | 5 ++- .../office/elevator/ui/main/MainScreen.kt | 7 ++- .../ui/main/store/MainStoreFactory.kt | 45 +++++++++++-------- .../office/elevator/ui/models/ReservedSeat.kt | 5 ++- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/Calendar.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/Calendar.kt index 4b4f0756..1d6ec02e 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/Calendar.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/Calendar.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Row 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.size import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme @@ -79,7 +80,9 @@ fun CalendarTitle( selectedDate: String ) { Row( - modifier = Modifier.fillMaxWidth(), + modifier = Modifier + .padding(horizontal = 16.dp) + .fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = CenterVertically ) { diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/MainScreen.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/MainScreen.kt index ac3e04bd..67679e8a 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/MainScreen.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/MainScreen.kt @@ -81,7 +81,9 @@ fun MainScreen(component: MainComponent) { ) if (showModalCalendar) { ModalCalendar( - modifier = Modifier.align(Alignment.Center), + modifier = Modifier + .padding(horizontal = 16.dp) + .align(Alignment.Center), onClickCansel = { component.onEvent(MainStore.Intent.OnClickCloseCalendar) }, onClickOk = { component.onEvent(MainStore.Intent.OnClickApplyDate(it)) }, currentDate = state.currentDate @@ -122,6 +124,7 @@ private fun SnackBarSuccessMessage(modifier: Modifier, isVisible: Boolean) { @Composable fun MainScreenContent( + modifier: Modifier = Modifier, reservedSeats: List, elevatorState: ElevatorState, onClickBook: () -> Unit, @@ -130,7 +133,7 @@ fun MainScreenContent( onClickOpenCalendar: () -> Unit ) { Column( - modifier = Modifier.fillMaxSize() + modifier = modifier.fillMaxSize() ) { Column ( modifier = Modifier diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStoreFactory.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStoreFactory.kt index 3096b782..72a57893 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStoreFactory.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/store/MainStoreFactory.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.datetime.Clock import kotlinx.datetime.LocalDate +import kotlinx.datetime.Month import kotlinx.datetime.TimeZone import kotlinx.datetime.toLocalDateTime import org.koin.core.component.KoinComponent @@ -32,23 +33,7 @@ internal class MainStoreFactory( name = "MainStore", initialState = MainStore.State( elevatorState = ElevatorState.Below, - reservedSeats = listOf( - ReservedSeat( - seatName = "Рабочее масто А1", - bookingDay = "Пн, 1 июля", - bookingTime = "12:00 - 14:00" - ), - ReservedSeat( - seatName = "Рабочее масто А1", - bookingDay = "Пн, 1 июля", - bookingTime = "12:00 - 14:00" - ), - ReservedSeat( - seatName = "Рабочее масто А1", - bookingDay = "Пн, 1 июля", - bookingTime = "12:00 - 14:00" - ), - ), + reservedSeats = listOf(), currentDate = getCurrentDate() ), executorFactory = ::ExecutorImpl, @@ -142,8 +127,32 @@ internal class MainStoreFactory( is Msg.UpdateSeatsReservation -> copy(reservedSeats = message.reservedSeats) is Msg.UpdateCurrentDate -> { if (message.date == null) this - else copy(currentDate = message.date) + else { + val reservedSeats = mokValue.filter { it.bookingDate == message.date } + copy(currentDate = message.date, reservedSeats = reservedSeats) + } } } } } + +private val mokValue = listOf( + ReservedSeat( + seatName = "Рабочее масто А2", + bookingDay = "Пн, 1 июля", + bookingTime = "12:00 - 14:00", + bookingDate = LocalDate(month = Month.JULY, year = 2023, dayOfMonth = 16) + ), + ReservedSeat( + seatName = "Рабочее масто А1", + bookingDay = "Пн, 1 июля", + bookingTime = "12:00 - 14:00", + bookingDate = LocalDate(month = Month.JULY, year = 2023, dayOfMonth = 17) + ), + ReservedSeat( + seatName = "Рабочее масто А3", + bookingDay = "Пн, 1 июля", + bookingTime = "12:00 - 14:00", + bookingDate = LocalDate(month = Month.JULY, year = 2023, dayOfMonth = 18) + ), +) \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/models/ReservedSeat.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/models/ReservedSeat.kt index 92ab69fe..629e9117 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/models/ReservedSeat.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/models/ReservedSeat.kt @@ -1,7 +1,10 @@ package band.effective.office.elevator.ui.models +import kotlinx.datetime.LocalDate + data class ReservedSeat( val seatName: String, val bookingDay: String, - val bookingTime: String + val bookingTime: String, + val bookingDate: LocalDate ) \ No newline at end of file -- GitLab From daae5a483be438b155d7c373a1389108488f8f9a Mon Sep 17 00:00:00 2001 From: Artem Gruzdev Date: Thu, 13 Jul 2023 17:22:18 +0600 Subject: [PATCH 3/3] [+] fix buttons --- .../office/elevator/components/EffectiveButton.kt | 6 +++--- .../office/elevator/ui/main/components/BookingCard.kt | 1 + .../office/elevator/ui/main/components/DateSelection.kt | 5 ++++- composeApp/src/commonMain/resources/MR/en/strings_en.xml | 7 +++++++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/EffectiveButton.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/EffectiveButton.kt index af55640e..90909c58 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/EffectiveButton.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/components/EffectiveButton.kt @@ -1,6 +1,5 @@ package band.effective.office.elevator.components -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Button @@ -10,9 +9,9 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import band.effective.office.elevator.MainRes @Composable fun EffectiveButton( @@ -24,7 +23,7 @@ fun EffectiveButton( onClick = onClick, colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.primary, - contentColor = MaterialTheme.colors.background + contentColor = Color.White ), modifier = modifier .clip(RoundedCornerShape(48.dp)) @@ -32,6 +31,7 @@ fun EffectiveButton( Text( text = buttonText, fontFamily = MaterialTheme.typography.button.fontFamily, + style = MaterialTheme.typography.button, fontSize = 15.sp, modifier = Modifier.padding(vertical = 10.dp) ) diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/BookingCard.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/BookingCard.kt index 4af02482..b8281339 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/BookingCard.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/BookingCard.kt @@ -68,6 +68,7 @@ fun BookingCard( Text( text = stringResource(MainRes.strings.show_map), fontSize = 15.sp, + style = MaterialTheme.typography.button, modifier = Modifier.padding(horizontal = 8.dp) ) } diff --git a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/DateSelection.kt b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/DateSelection.kt index f2bc505f..b781b3a2 100644 --- a/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/DateSelection.kt +++ b/composeApp/src/commonMain/kotlin/band/effective/office/elevator/ui/main/components/DateSelection.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.material.MaterialTheme import androidx.compose.material.Text 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.unit.dp @@ -36,7 +37,9 @@ fun DateSelection(onClickOpenCalendar: () -> Unit) { @Composable fun CalendarTitle(onClickOpenCalendar: () -> Unit) { Row ( - modifier = Modifier.clickable { onClickOpenCalendar() } + modifier = Modifier + .clickable { onClickOpenCalendar() }, + verticalAlignment = Alignment.CenterVertically ) { Image( painter = painterResource(MainRes.images.material_calendar_ic), diff --git a/composeApp/src/commonMain/resources/MR/en/strings_en.xml b/composeApp/src/commonMain/resources/MR/en/strings_en.xml index ff68b71d..20a4f905 100644 --- a/composeApp/src/commonMain/resources/MR/en/strings_en.xml +++ b/composeApp/src/commonMain/resources/MR/en/strings_en.xml @@ -19,6 +19,13 @@ Booking Employees + Elevator on the 1st floor + The elevator is coming + The elevator is up + Lift the elevator + Wait... + Call the elevator via the button + You need to sign in for the app to work Network connection error -- GitLab