diff --git a/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/chip/ReadOnlyTextChip.kt b/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/chip/ReadOnlyTextChip.kt new file mode 100644 index 0000000000..683aaa0e13 --- /dev/null +++ b/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/chip/ReadOnlyTextChip.kt @@ -0,0 +1,60 @@ +package `in`.koreatech.koin.core.designsystem.component.chip + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +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.Shape +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import `in`.koreatech.koin.core.designsystem.theme.KoinTheme + +/** + * 선택 불가한 텍스트 칩 + * @param title 텍스트 + * @param modifier Modifier + * @param containerColor 칩 배경색 + * @param textStyle 텍스트 스타일 + * @param shape 칩 모양 + * @param contentPadding 칩 내부 padding + */ +@Composable +fun ReadOnlyTextChip( + title: String, + modifier: Modifier = Modifier, + containerColor: Color = KoinTheme.colors.primary500, + textStyle: TextStyle = KoinTheme.typography.regular12, + shape: Shape = RoundedCornerShape(4.dp), + contentPadding: PaddingValues = PaddingValues(horizontal = 4.dp) +) { + Box( + modifier = modifier + .clip(shape) + .background(containerColor) + .padding(contentPadding), + contentAlignment = Alignment.Center + ) { + Text( + text = title, + style = textStyle, + ) + } +} + +@Preview +@Composable +private fun ReadOnlyTextChipPreview() { + ReadOnlyTextChip( + title = "순환", + containerColor = Color(0xFF4ED92C), + textStyle = KoinTheme.typography.regular12.copy(color = Color.White) + ) +} diff --git a/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/chip/TextChipGroup.kt b/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/chip/TextChipGroup.kt index 63291454d8..39f6459824 100644 --- a/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/chip/TextChipGroup.kt +++ b/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/chip/TextChipGroup.kt @@ -31,12 +31,12 @@ import `in`.koreatech.koin.core.designsystem.component.chip.ChipOverflowStrategy */ @Composable fun TextChipGroup( - modifier: Modifier = Modifier, - chipOverflowStrategy: ChipOverflowStrategy = Flow(), titles: List, - shape: Shape = RoundedCornerShape(50), vararg selectedChipIndexes: Int, onChipSelected: (title: String) -> Unit, + modifier: Modifier = Modifier, + chipOverflowStrategy: ChipOverflowStrategy = Flow(), + shape: Shape = RoundedCornerShape(50), showClickRipple: Boolean = true, contentPadding: PaddingValues = PaddingValues(vertical = 6.dp, horizontal = 12.dp), horizontalArrangement: Arrangement.Horizontal = Arrangement.spacedBy(6.dp), diff --git a/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/tab/KoinSurface.kt b/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/tab/KoinSurface.kt new file mode 100644 index 0000000000..4e801b3630 --- /dev/null +++ b/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/tab/KoinSurface.kt @@ -0,0 +1,35 @@ +package `in`.koreatech.koin.core.designsystem.component.tab + +import androidx.compose.foundation.BorderStroke +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.RectangleShape +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +@Composable +fun KoinSurface( + modifier: Modifier = Modifier, + shape: Shape = RectangleShape, + color: Color = Color.White, + contentColor: Color = Color.Black, + tonalElevation: Dp = 0.dp, + shadowElevation: Dp = 0.dp, + border: BorderStroke? = null, + content: @Composable () -> Unit +) { + + Surface( + modifier = modifier, + shape = shape, + color = color, + contentColor = contentColor, + tonalElevation = tonalElevation, + shadowElevation = shadowElevation, + border = border, + content = content + ) +} \ No newline at end of file diff --git a/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/topbar/KoinTopAppBar.kt b/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/topbar/KoinTopAppBar.kt index e42b59901f..c9f1526ba9 100644 --- a/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/topbar/KoinTopAppBar.kt +++ b/core/designsystem/src/main/java/in/koreatech/koin/core/designsystem/component/topbar/KoinTopAppBar.kt @@ -14,16 +14,19 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import `in`.koreatech.koin.core.designsystem.R import `in`.koreatech.koin.core.designsystem.noRippleClickable +import `in`.koreatech.koin.core.designsystem.theme.KoinTheme @OptIn(ExperimentalMaterial3Api::class) @Composable fun KoinTopAppBar( title: String, modifier: Modifier = Modifier, + textStyle: TextStyle = KoinTheme.typography.medium18, onNavigationIconClick: () -> Unit = {}, actions: @Composable() (RowScope.() -> Unit) = {}, colors: TopAppBarColors = TopAppBarDefaults.centerAlignedTopAppBarColors( @@ -35,7 +38,10 @@ fun KoinTopAppBar( ) { CenterAlignedTopAppBar( title = { - Text(title) + Text( + text = title, + style = textStyle, + ) }, modifier = modifier, navigationIcon = { diff --git a/core/designsystem/src/main/res/drawable/ic_caution.xml b/core/designsystem/src/main/res/drawable/ic_caution.xml new file mode 100644 index 0000000000..6431e12750 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_caution.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/feature/bus/build.gradle.kts b/feature/bus/build.gradle.kts index 0c8d53ab43..bac9fe443b 100644 --- a/feature/bus/build.gradle.kts +++ b/feature/bus/build.gradle.kts @@ -2,6 +2,7 @@ plugins { alias(libs.plugins.koin.library) alias(libs.plugins.koin.hilt) alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlinx.serialization) } android { @@ -24,10 +25,14 @@ dependencies { implementation(libs.core.ktx) implementation(libs.appcompat) implementation(libs.material) + implementation(libs.kotlinxCollectionsImmutable) implementation(platform(libs.compose.bom)) implementation(libs.bundles.compose.m3) debugImplementation(libs.bundles.compose.debug.test) androidTestImplementation(libs.compose.ui.test.manifest) + + implementation("androidx.navigation:navigation-compose:2.8.3") + implementation(libs.kotlinx.serialization.json) } \ No newline at end of file diff --git a/feature/bus/src/main/java/in/koreatech/bus/Bus2Activity.kt b/feature/bus/src/main/java/in/koreatech/bus/Bus2Activity.kt index 6e2946feaf..e2eba259fb 100644 --- a/feature/bus/src/main/java/in/koreatech/bus/Bus2Activity.kt +++ b/feature/bus/src/main/java/in/koreatech/bus/Bus2Activity.kt @@ -3,10 +3,15 @@ package `in`.koreatech.bus import android.os.Bundle import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.MaterialTheme +import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat +import androidx.navigation.compose.rememberNavController +import `in`.koreatech.bus.navigation.BusNavigation import `in`.koreatech.koin.feature.bus.R class Bus2Activity : AppCompatActivity() { @@ -16,7 +21,10 @@ class Bus2Activity : AppCompatActivity() { setContentView(R.layout.activity_bus2) findViewById(R.id.compose_view_bus).setContent { MaterialTheme { - + BusNavigation( + modifier = Modifier.fillMaxSize(), + navController = rememberNavController(), + ) } } } diff --git a/feature/bus/src/main/java/in/koreatech/bus/navigation/BusNavigation.kt b/feature/bus/src/main/java/in/koreatech/bus/navigation/BusNavigation.kt new file mode 100644 index 0000000000..00341c717c --- /dev/null +++ b/feature/bus/src/main/java/in/koreatech/bus/navigation/BusNavigation.kt @@ -0,0 +1,36 @@ +package `in`.koreatech.bus.navigation + +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavHostController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import `in`.koreatech.bus.screen.timetable.viewmodel.BusViewModel + +@Composable +fun BusNavigation( + modifier: Modifier = Modifier, + navController: NavHostController = rememberNavController(), + viewModel: BusViewModel = hiltViewModel() +) { + + NavHost( + modifier = modifier, + navController = navController, + startDestination = Routes.BusTimetable, + enterTransition = { + EnterTransition.None + }, exitTransition = { + ExitTransition.None + } + ) { + + composable { + + } + } +} \ No newline at end of file diff --git a/feature/bus/src/main/java/in/koreatech/bus/navigation/Routes.kt b/feature/bus/src/main/java/in/koreatech/bus/navigation/Routes.kt new file mode 100644 index 0000000000..9b4fc63f52 --- /dev/null +++ b/feature/bus/src/main/java/in/koreatech/bus/navigation/Routes.kt @@ -0,0 +1,8 @@ +package `in`.koreatech.bus.navigation + +import kotlinx.serialization.Serializable + +internal object Routes { + + @Serializable data object BusTimetable +} \ No newline at end of file diff --git a/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/composable/BusTimetableScreen.kt b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/composable/BusTimetableScreen.kt new file mode 100644 index 0000000000..44d87e7bcf --- /dev/null +++ b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/composable/BusTimetableScreen.kt @@ -0,0 +1,157 @@ +package `in`.koreatech.bus.screen.timetable.composable + +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +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.lazy.LazyColumn +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import `in`.koreatech.bus.screen.timetable.type.BusType +import `in`.koreatech.bus.screen.timetable.type.ShuttleBusRouteType +import `in`.koreatech.bus.screen.timetable.viewmodel.BusTimetableViewModel +import `in`.koreatech.bus.viewstate.ShuttleRegionViewState +import `in`.koreatech.bus.viewstate.ShuttleTimetableOverviewViewState +import `in`.koreatech.koin.core.designsystem.component.chip.TextChipGroup +import `in`.koreatech.koin.core.designsystem.component.tab.KoinTabRow +import `in`.koreatech.koin.core.designsystem.component.text.LeadingIconText +import `in`.koreatech.koin.core.designsystem.component.topbar.KoinTopAppBar +import `in`.koreatech.koin.core.designsystem.theme.KoinTheme +import `in`.koreatech.koin.feature.bus.R +import kotlinx.collections.immutable.persistentListOf + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) +@Composable +internal fun BusTimetableScreen( + modifier: Modifier = Modifier, + onNavigationIconClick: () -> Unit = {}, + viewModel: BusTimetableViewModel = hiltViewModel() +) { + + var selectedTimetableTypeTabIndex by rememberSaveable { mutableIntStateOf(0) } + + Column( + modifier = modifier + ) { + KoinTopAppBar( + title = stringResource(R.string.title_bus_timetable), + onNavigationIconClick = onNavigationIconClick + ) + + LazyColumn { + item { + Column( + modifier = Modifier.fillMaxWidth().background(Color.White).padding(start = 24.dp) + ) { + Text( + text = stringResource(R.string.shuttle_timetable), + style = KoinTheme.typography.bold20 + ) + Spacer(modifier = Modifier.height(8.dp)) + LeadingIconText( + text = stringResource(R.string.request_for_incorrect_information), + iconRes = R.drawable.ic_caution + ) + } + } + + stickyHeader { + KoinTabRow( + titles = BusType.entries.map { stringResource(it.titleRes) }, + selectedTabIndex = selectedTimetableTypeTabIndex, + onTabSelected = { selectedTimetableTypeTabIndex = it } + ) + } + + item { + when(selectedTimetableTypeTabIndex) { + BusType.SHUTTLE.ordinal -> { + ShuttleTimetableScreen( + modifier = Modifier.fillMaxSize().background(KoinTheme.colors.neutral100), + regions = persistentListOf( + ShuttleRegionViewState( + name = "서울", + timetableOverviews = listOf( + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKDAY, + name = "서울-대전", + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKEND, + name = "서울-대전", + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.CIRCULATION, + name = "서울-대전", + ) + ) + ), + ShuttleRegionViewState( + name = "대전", + timetableOverviews = listOf( + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKDAY, + name = "대전-서울", + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKEND, + name = "대전-서울", + description = "대전에서 서울로 이동하는 노선입니다." + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.CIRCULATION, + name = "대전-서울", + description = "대전에서 서울로 이동하는 노선입니다." + ) + ) + ), + ShuttleRegionViewState( + name = "대구", + timetableOverviews = listOf( + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKDAY, + name = "대구-서울", + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKDAY, + name = "대구-서울", + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKEND, + name = "대구-서울", + ) + ) + ) + ) + ) + } + } + } + } + } +} + + +@Preview(showBackground = true) +@Composable +private fun BusTimetableScreenPreview() { + BusTimetableScreen( + modifier = Modifier.fillMaxSize() + ) +} \ No newline at end of file diff --git a/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/composable/ShuttleTimetableScreen.kt b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/composable/ShuttleTimetableScreen.kt new file mode 100644 index 0000000000..b084e5e700 --- /dev/null +++ b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/composable/ShuttleTimetableScreen.kt @@ -0,0 +1,199 @@ +package `in`.koreatech.bus.screen.timetable.composable + +import androidx.compose.foundation.background +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.material.icons.Icons +import androidx.compose.material.icons.automirrored.rounded.KeyboardArrowRight +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import `in`.koreatech.bus.screen.timetable.type.ShuttleBusRouteType +import `in`.koreatech.bus.viewstate.ShuttleRegionViewState +import `in`.koreatech.bus.viewstate.ShuttleTimetableOverviewViewState +import `in`.koreatech.koin.core.designsystem.component.chip.ReadOnlyTextChip +import `in`.koreatech.koin.core.designsystem.component.chip.TextChipGroup +import `in`.koreatech.koin.core.designsystem.component.tab.KoinSurface +import `in`.koreatech.koin.core.designsystem.theme.KoinTheme +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf + +@Composable +internal fun ShuttleTimetableScreen( + modifier: Modifier = Modifier, + regions: ImmutableList +) { + + var selectedRouteTypeIndex by rememberSaveable { mutableIntStateOf(ShuttleBusRouteType.ALL.ordinal) } + val context = LocalContext.current + + Column( + modifier = modifier + ) { + TextChipGroup( + modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp, horizontal = 24.dp), + titles = ShuttleBusRouteType.entries.map { stringResource(it.titleRes) }, + onChipSelected = { title -> + selectedRouteTypeIndex = ShuttleBusRouteType.entries.find { context.getString(it.titleRes) == title }?.ordinal ?: 0 + }, + selectedChipIndexes = intArrayOf(selectedRouteTypeIndex) + ) + regions.forEach { + ShuttleRegionView( + modifier = Modifier, + region = it + ) + if (it != regions.last()) { + Spacer(modifier = Modifier.height(10.dp)) + } + } + } +} + +@Composable +private fun ShuttleRegionView( + modifier: Modifier = Modifier, + region: ShuttleRegionViewState +) { + KoinSurface( + modifier = modifier + ) { + Column( + modifier = Modifier.padding(horizontal = 24.dp).padding(top = 16.dp, bottom = 4.dp) + ) { + Text( + text = region.name, + style = KoinTheme.typography.bold18, + ) + region.timetableOverviews.forEach { + ShuttleRouteItem( + modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp, vertical = 10.dp), + timetableOverview = it + ) + } + } + } +} + +@Composable +private fun ShuttleRouteItem( + modifier: Modifier = Modifier, + timetableOverview: ShuttleTimetableOverviewViewState +) { + Column( + modifier = modifier + ) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + ReadOnlyTextChip( + title = stringResource(timetableOverview.routeType.simpleTitleRes), + containerColor = when (timetableOverview.routeType) { // TODO : 색상 정리 + ShuttleBusRouteType.WEEKDAY -> Color(0xFF34ADFF) + ShuttleBusRouteType.WEEKEND -> Color(0xFFFFB443) + ShuttleBusRouteType.CIRCULATION -> Color(0xFF4ED92C) + else -> Color.Transparent + }, + textStyle = KoinTheme.typography.regular12.copy(color = Color.White) + ) + + Text( + text = timetableOverview.name, + style = KoinTheme.typography.medium16, + modifier = Modifier.padding(start = 8.dp) + ) + Spacer(modifier = Modifier.weight(1f)) + Icon( + imageVector = Icons.AutoMirrored.Rounded.KeyboardArrowRight, + contentDescription = timetableOverview.name, + tint = KoinTheme.colors.neutral400 + ) + } + if (timetableOverview.description.isNotEmpty()) + Text( + text = timetableOverview.description, + style = KoinTheme.typography.regular12, + color = KoinTheme.colors.neutral500, + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun ShuttleTimetableScreenPreview() { + ShuttleTimetableScreen( + modifier = Modifier.fillMaxSize().background(KoinTheme.colors.neutral100), + regions = persistentListOf( + ShuttleRegionViewState( + name = "서울", + timetableOverviews = listOf( + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKDAY, + name = "서울-대전", + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKEND, + name = "서울-대전", + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.CIRCULATION, + name = "서울-대전", + ) + ) + ), + ShuttleRegionViewState( + name = "대전", + timetableOverviews = listOf( + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKDAY, + name = "대전-서울", + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKEND, + name = "대전-서울", + description = "대전에서 서울로 이동하는 노선입니다." + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.CIRCULATION, + name = "대전-서울", + description = "대전에서 서울로 이동하는 노선입니다." + ) + ) + ), + ShuttleRegionViewState( + name = "대구", + timetableOverviews = listOf( + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKDAY, + name = "대구-서울", + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKDAY, + name = "대구-서울", + ), + ShuttleTimetableOverviewViewState( + routeType = ShuttleBusRouteType.WEEKEND, + name = "대구-서울", + ) + ) + ) + ) + ) +} \ No newline at end of file diff --git a/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/type/BusType.kt b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/type/BusType.kt new file mode 100644 index 0000000000..3f7cdc4630 --- /dev/null +++ b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/type/BusType.kt @@ -0,0 +1,12 @@ +package `in`.koreatech.bus.screen.timetable.type + +import androidx.annotation.StringRes +import `in`.koreatech.koin.feature.bus.R + +internal enum class BusType( + @StringRes val titleRes: Int +) { + SHUTTLE(R.string.tab_shuttle), + EXPRESS(R.string.tab_express), + CITY(R.string.tab_city), +} \ No newline at end of file diff --git a/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/type/ShuttleBusRouteType.kt b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/type/ShuttleBusRouteType.kt new file mode 100644 index 0000000000..b84afe6d45 --- /dev/null +++ b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/type/ShuttleBusRouteType.kt @@ -0,0 +1,14 @@ +package `in`.koreatech.bus.screen.timetable.type + +import androidx.annotation.StringRes +import `in`.koreatech.koin.feature.bus.R + +enum class ShuttleBusRouteType( + @StringRes val titleRes: Int, + @StringRes val simpleTitleRes: Int +) { + ALL(R.string.all_routes, 0), + WEEKDAY(R.string.weekday_routes, R.string.weekday_routes_simple), + WEEKEND(R.string.weekend_routes, R.string.weekend_routes_simple), + CIRCULATION(R.string.circulation_routes, R.string.circulation_routes_simple), +} \ No newline at end of file diff --git a/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/viewmodel/BusTimetableViewModel.kt b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/viewmodel/BusTimetableViewModel.kt new file mode 100644 index 0000000000..ffd834b4ae --- /dev/null +++ b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/viewmodel/BusTimetableViewModel.kt @@ -0,0 +1,12 @@ +package `in`.koreatech.bus.screen.timetable.viewmodel + +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class BusTimetableViewModel @Inject constructor( + +) : ViewModel() { + +} \ No newline at end of file diff --git a/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/viewmodel/BusViewModel.kt b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/viewmodel/BusViewModel.kt new file mode 100644 index 0000000000..aa0234d350 --- /dev/null +++ b/feature/bus/src/main/java/in/koreatech/bus/screen/timetable/viewmodel/BusViewModel.kt @@ -0,0 +1,11 @@ +package `in`.koreatech.bus.screen.timetable.viewmodel + +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class BusViewModel @Inject constructor( + +) : ViewModel() { +} \ No newline at end of file diff --git a/feature/bus/src/main/java/in/koreatech/bus/viewstate/ShuttleTimetableOverviewViewState.kt b/feature/bus/src/main/java/in/koreatech/bus/viewstate/ShuttleTimetableOverviewViewState.kt new file mode 100644 index 0000000000..e36b39fe07 --- /dev/null +++ b/feature/bus/src/main/java/in/koreatech/bus/viewstate/ShuttleTimetableOverviewViewState.kt @@ -0,0 +1,19 @@ +package `in`.koreatech.bus.viewstate + +import androidx.compose.runtime.Immutable +import `in`.koreatech.bus.screen.timetable.type.ShuttleBusRouteType + +@Immutable +data class ShuttleTimetableOverviewViewState( + val routeType: ShuttleBusRouteType, + val name: String, + val description: String = "", +) + +@Immutable +data class ShuttleRegionViewState( + val name: String, + val timetableOverviews: List +) + +// TODO : 임시 데이터, API 아직 없음 \ No newline at end of file diff --git a/feature/bus/src/main/res/values/strings.xml b/feature/bus/src/main/res/values/strings.xml index 73862c416f..caaed9e722 100644 --- a/feature/bus/src/main/res/values/strings.xml +++ b/feature/bus/src/main/res/values/strings.xml @@ -1 +1,19 @@ - \ No newline at end of file + + + 버스 시간표 + 교내 셔틀 시간표 + 정보가 정확하지 않나요? + 셔틀 + 대성 + 시내 + 전체 + 주중노선 + 주말노선 + 순환노선 + 주중 + 주말 + 순환 + + + + \ No newline at end of file