diff --git a/core/designsystem/src/main/java/com/terning/core/designsystem/component/button/SortingButton.kt b/core/designsystem/src/main/java/com/terning/core/designsystem/component/button/SortingButton.kt
index 324962c8..8cf9ac65 100644
--- a/core/designsystem/src/main/java/com/terning/core/designsystem/component/button/SortingButton.kt
+++ b/core/designsystem/src/main/java/com/terning/core/designsystem/component/button/SortingButton.kt
@@ -1,5 +1,6 @@
package com.terning.core.designsystem.component.button
+import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
@@ -11,11 +12,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import com.terning.core.designsystem.R
import com.terning.core.designsystem.extension.noRippleClickable
+import com.terning.core.designsystem.theme.Black
import com.terning.core.designsystem.theme.Grey350
import com.terning.core.designsystem.theme.TerningTheme
import com.terning.core.designsystem.type.SortBy
@@ -27,36 +30,31 @@ fun SortingButton(
onCLick: () -> Unit,
) {
Row(
- verticalAlignment = Alignment.CenterVertically,
modifier = modifier
- .border(
- width = 1.dp,
- color = Grey350,
- shape = RoundedCornerShape(5.dp)
- )
.noRippleClickable(onCLick),
) {
- Icon(
- imageVector = ImageVector.vectorResource(id = R.drawable.ic_down_18),
- contentDescription = stringResource(id = R.string.sort_button_description),
- tint = Grey350,
- modifier = Modifier
- .padding(
- start = 7.dp,
- end = 6.dp,
- top = 5.dp,
- bottom = 5.dp,
- )
- .size(20.dp)
- )
Text(
text = stringResource(
id = SortBy.entries[sortBy].sortBy
),
style = TerningTheme.typography.button3,
- color = Grey350,
+ color = Black,
+ modifier = Modifier
+ .padding(
+ top = 6.dp,
+ bottom = 6.dp,
+ )
+ )
+ Image(
+ painter = painterResource(id = R.drawable.ic_down_18),
+ contentDescription = stringResource(id = R.string.sort_button_description),
modifier = Modifier
- .padding(end = 11.dp)
+ .padding(
+ start = 2.dp,
+ end = 2.dp,
+ top = 6.dp,
+ bottom = 4.dp,
+ )
)
}
-}
+}
\ No newline at end of file
diff --git a/core/designsystem/src/main/java/com/terning/core/designsystem/type/JobType.kt b/core/designsystem/src/main/java/com/terning/core/designsystem/type/JobType.kt
new file mode 100644
index 00000000..37030eda
--- /dev/null
+++ b/core/designsystem/src/main/java/com/terning/core/designsystem/type/JobType.kt
@@ -0,0 +1,36 @@
+package com.terning.core.designsystem.type
+
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+import com.terning.core.designsystem.R
+
+enum class JobType(
+ val stringValue: String,
+ @DrawableRes val drawableResId: Int,
+ @StringRes val stringResId: Int,
+) {
+ PLAN("plan", R.drawable.ic_job_plan_24, R.string.job_type_plan),
+ MARKETING("marketing", R.drawable.ic_job_marketing_24, R.string.job_type_marketing),
+ SALES("sales", R.drawable.ic_job_sales_24, R.string.job_type_sales),
+ ADMIN("admin", R.drawable.ic_job_accounting_24, R.string.job_type_admin),
+ DESIGN("design", R.drawable.ic_job_design_24, R.string.job_type_design),
+ IT("it", R.drawable.ic_job_it_24, R.string.job_type_it),
+ RESEARCH("research", R.drawable.ic_job_research_24, R.string.job_type_research),
+ ETC("etc", R.drawable.ic_job_extra_24, R.string.job_type_etc),
+ TOTAL("total", R.drawable.ic_job_all_24, R.string.job_type_total), ;
+
+
+ companion object {
+ fun fromString(value: String?): JobType = when (value) {
+ "plan" -> PLAN
+ "marketing" -> MARKETING
+ "admin" -> ADMIN
+ "sales" -> SALES
+ "design" -> DESIGN
+ "it" -> IT
+ "research" -> RESEARCH
+ "etc" -> ETC
+ else -> TOTAL
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/designsystem/src/main/res/drawable/ic_job_accounting_24.xml b/core/designsystem/src/main/res/drawable/ic_job_accounting_24.xml
new file mode 100644
index 00000000..a6e01c86
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_job_accounting_24.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/designsystem/src/main/res/drawable/ic_job_all_24.xml b/core/designsystem/src/main/res/drawable/ic_job_all_24.xml
new file mode 100644
index 00000000..be926f90
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_job_all_24.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
diff --git a/core/designsystem/src/main/res/drawable/ic_job_design_24.xml b/core/designsystem/src/main/res/drawable/ic_job_design_24.xml
new file mode 100644
index 00000000..f8c06562
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_job_design_24.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
diff --git a/core/designsystem/src/main/res/drawable/ic_job_extra_24.xml b/core/designsystem/src/main/res/drawable/ic_job_extra_24.xml
new file mode 100644
index 00000000..2368d1f2
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_job_extra_24.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
diff --git a/core/designsystem/src/main/res/drawable/ic_job_it_24.xml b/core/designsystem/src/main/res/drawable/ic_job_it_24.xml
new file mode 100644
index 00000000..73ce99d7
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_job_it_24.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
diff --git a/core/designsystem/src/main/res/drawable/ic_job_marketing_24.xml b/core/designsystem/src/main/res/drawable/ic_job_marketing_24.xml
new file mode 100644
index 00000000..7fded015
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_job_marketing_24.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
diff --git a/core/designsystem/src/main/res/drawable/ic_job_plan_24.xml b/core/designsystem/src/main/res/drawable/ic_job_plan_24.xml
new file mode 100644
index 00000000..e3509dfe
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_job_plan_24.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/designsystem/src/main/res/drawable/ic_job_research_24.xml b/core/designsystem/src/main/res/drawable/ic_job_research_24.xml
new file mode 100644
index 00000000..83d0f880
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_job_research_24.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
diff --git a/core/designsystem/src/main/res/drawable/ic_job_sales_24.xml b/core/designsystem/src/main/res/drawable/ic_job_sales_24.xml
new file mode 100644
index 00000000..25793d5e
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_job_sales_24.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/designsystem/src/main/res/values/strings.xml b/core/designsystem/src/main/res/values/strings.xml
index 70126b08..ab956787 100644
--- a/core/designsystem/src/main/res/values/strings.xml
+++ b/core/designsystem/src/main/res/values/strings.xml
@@ -72,17 +72,22 @@
닉네임은 12자리 이내로 설정해 주세요
- 필터링 재설정
- 재학 상태
- 저장하기
1학년
2학년
3학년
4학년
- 희망 근무 기간
1 ~ 3개월
4 ~ 6개월
7개월 이상
- 근무 시작 시기
+
+ 기획/전략
+ 마케팅/홍보
+ 사무/회계
+ 인사/영업
+ 디자인/예술
+ 개발/IT
+ 연구/생산
+ 기타
+ 전체 직무
\ No newline at end of file
diff --git a/data/home/src/main/java/com/terning/data/home/dto/request/ChangeFilterRequestDto.kt b/data/home/src/main/java/com/terning/data/home/dto/request/ChangeFilterRequestDto.kt
index e476b414..126ddada 100644
--- a/data/home/src/main/java/com/terning/data/home/dto/request/ChangeFilterRequestDto.kt
+++ b/data/home/src/main/java/com/terning/data/home/dto/request/ChangeFilterRequestDto.kt
@@ -7,13 +7,15 @@ import kotlinx.serialization.Serializable
@Serializable
data class ChangeFilterRequestDto(
@SerialName("grade")
- val grade: String,
+ val grade: String?,
@SerialName("workingPeriod")
- val workingPeriod: String,
+ val workingPeriod: String?,
@SerialName("startYear")
- val startYear: Int,
+ val startYear: Int?,
@SerialName("startMonth")
- val startMonth: Int,
+ val startMonth: Int?,
+ @SerialName("jobType")
+ val jobType: String,
)
fun ChangeFilteringRequestModel.toChangeFilterRequestDto(): ChangeFilterRequestDto =
@@ -22,4 +24,5 @@ fun ChangeFilteringRequestModel.toChangeFilterRequestDto(): ChangeFilterRequestD
workingPeriod = workingPeriod,
startYear = startYear,
startMonth = startMonth,
+ jobType = jobType,
)
diff --git a/data/home/src/main/java/com/terning/data/home/dto/response/HomeFilteringInfoResponseDto.kt b/data/home/src/main/java/com/terning/data/home/dto/response/HomeFilteringInfoResponseDto.kt
index 699a9a58..37bb4862 100644
--- a/data/home/src/main/java/com/terning/data/home/dto/response/HomeFilteringInfoResponseDto.kt
+++ b/data/home/src/main/java/com/terning/data/home/dto/response/HomeFilteringInfoResponseDto.kt
@@ -13,4 +13,6 @@ data class HomeFilteringInfoResponseDto(
val startYear: Int?,
@SerialName("startMonth")
val startMonth: Int?,
+ @SerialName("jobType")
+ val jobType: String,
)
diff --git a/data/home/src/main/java/com/terning/data/home/mapper/HomeFilteringInfoMapper.kt b/data/home/src/main/java/com/terning/data/home/mapper/HomeFilteringInfoMapper.kt
index dc32a148..7ba34cb7 100644
--- a/data/home/src/main/java/com/terning/data/home/mapper/HomeFilteringInfoMapper.kt
+++ b/data/home/src/main/java/com/terning/data/home/mapper/HomeFilteringInfoMapper.kt
@@ -9,4 +9,5 @@ fun HomeFilteringInfoResponseDto.toHomeFilteringInfo(): HomeFilteringInfo =
workingPeriod = this.workingPeriod,
startYear = this.startYear,
startMonth = this.startMonth,
+ jobType = this.jobType,
)
\ No newline at end of file
diff --git a/domain/home/src/main/java/com/terning/domain/home/entity/ChangeFilteringRequestModel.kt b/domain/home/src/main/java/com/terning/domain/home/entity/ChangeFilteringRequestModel.kt
index ab722760..7da40f18 100644
--- a/domain/home/src/main/java/com/terning/domain/home/entity/ChangeFilteringRequestModel.kt
+++ b/domain/home/src/main/java/com/terning/domain/home/entity/ChangeFilteringRequestModel.kt
@@ -1,8 +1,9 @@
package com.terning.domain.home.entity
data class ChangeFilteringRequestModel(
- val grade: String,
- val workingPeriod: String,
- val startYear: Int,
- val startMonth: Int,
+ val grade: String?,
+ val workingPeriod: String?,
+ val startYear: Int?,
+ val startMonth: Int?,
+ val jobType: String,
)
diff --git a/domain/home/src/main/java/com/terning/domain/home/entity/HomeFilteringInfo.kt b/domain/home/src/main/java/com/terning/domain/home/entity/HomeFilteringInfo.kt
index 9f117640..1a8392e6 100644
--- a/domain/home/src/main/java/com/terning/domain/home/entity/HomeFilteringInfo.kt
+++ b/domain/home/src/main/java/com/terning/domain/home/entity/HomeFilteringInfo.kt
@@ -5,4 +5,5 @@ data class HomeFilteringInfo(
val workingPeriod: String?,
val startYear: Int?,
val startMonth: Int?,
+ val jobType: String,
)
diff --git a/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt b/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt
index ba0a25c7..ee307342 100644
--- a/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt
+++ b/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt
@@ -32,7 +32,6 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.terning.core.analytics.EventType
import com.terning.core.analytics.LocalTracker
import com.terning.core.designsystem.component.bottomsheet.SortingBottomSheet
-import com.terning.core.designsystem.component.button.SortingButton
import com.terning.core.designsystem.component.image.TerningImage
import com.terning.core.designsystem.component.item.InternItemWithShadow
import com.terning.core.designsystem.extension.noRippleClickable
@@ -44,20 +43,20 @@ import com.terning.core.designsystem.theme.Grey400
import com.terning.core.designsystem.theme.TerningMain
import com.terning.core.designsystem.theme.TerningTheme
import com.terning.core.designsystem.theme.White
-import com.terning.core.designsystem.type.Grade
-import com.terning.core.designsystem.type.WorkingPeriod
+import com.terning.core.designsystem.type.JobType
import com.terning.domain.home.entity.HomeFilteringInfo
import com.terning.domain.home.entity.HomeRecommendedIntern
import com.terning.domain.home.entity.HomeUpcomingIntern
import com.terning.feature.dialog.cancel.ScrapCancelDialog
import com.terning.feature.dialog.detail.ScrapDialog
-import com.terning.feature.home.component.HomeFilteringBottomSheet
import com.terning.feature.home.component.HomeFilteringScreen
import com.terning.feature.home.component.HomeRecommendEmptyIntern
+import com.terning.feature.home.component.HomeSortingButton
import com.terning.feature.home.component.HomeUpcomingEmptyFilter
import com.terning.feature.home.component.HomeUpcomingEmptyIntern
import com.terning.feature.home.component.HomeUpcomingInternScreen
-import okhttp3.internal.toImmutableList
+import com.terning.feature.home.component.bottomsheet.HomeFilteringBottomSheet
+import kotlinx.collections.immutable.toImmutableList
const val NAME_MAX_LENGTH = 5
private const val ZERO_TOTAL_COUNT = 0
@@ -150,13 +149,21 @@ fun HomeScreen(
val homeFilteringInfo = when (homeState.homeFilteringInfoState) {
is UiState.Success -> (homeState.homeFilteringInfoState as UiState.Success).data
- else -> HomeFilteringInfo(null, null, null, null)
+ else -> HomeFilteringInfo(
+ grade = null,
+ workingPeriod = null,
+ startYear = null,
+ startMonth = null,
+ jobType = JobType.TOTAL.stringValue
+ )
}
val homeRecommendInternTotal = remember(recommendedInternList.loadState.refresh) {
- if(recommendedInternList.itemCount > 0) {
+ if (recommendedInternList.itemCount > 0) {
recommendedInternList[0]?.totalCount ?: ZERO_TOTAL_COUNT
- } else { ZERO_TOTAL_COUNT }
+ } else {
+ ZERO_TOTAL_COUNT
+ }
}
var changeFilteringSheetState by remember { mutableStateOf(false) }
@@ -187,19 +194,14 @@ fun HomeScreen(
if (changeFilteringSheetState) {
HomeFilteringBottomSheet(
- defaultGrade = homeFilteringInfo.grade?.let { Grade.fromString(it) },
- defaultWorkingPeriod = homeFilteringInfo.workingPeriod?.let {
- WorkingPeriod.fromString(it)
- },
- defaultStartYear = homeFilteringInfo.startYear,
- defaultStartMonth = homeFilteringInfo.startMonth,
onDismiss = { changeFilteringSheetState = false },
- onChangeButtonClick = { grade, workingPeriod, year, month ->
+ defaultFilteringInfo = homeFilteringInfo,
+ onChangeButtonClick = { grade, workingPeriod, year, month, jobType ->
amplitudeTracker.track(
type = EventType.CLICK,
name = "home_filtering_save"
)
- viewModel.putFilteringInfo(grade, workingPeriod, year, month)
+ viewModel.putFilteringInfo(grade, workingPeriod, year, month, jobType)
changeFilteringSheetState = false
}
)
@@ -306,7 +308,7 @@ fun HomeScreen(
)
}
Spacer(modifier = Modifier.weight(1f))
- SortingButton(
+ HomeSortingButton(
sortBy = homeState.sortBy.ordinal,
onCLick = { updateSortingSheetVisibility(true) },
)
@@ -319,13 +321,10 @@ fun HomeScreen(
}
}
-
if (recommendedInternList.itemCount == 0) {
item {
HomeRecommendEmptyIntern(
- text =
- if (homeState.homeFilteringInfoState is UiState.Success && homeFilteringInfo.grade == null) R.string.home_recommend_no_filtering
- else R.string.home_recommend_no_intern
+ text = R.string.home_recommend_no_intern
)
}
} else {
diff --git a/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt b/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt
index ffb82a7a..ed55e3ac 100644
--- a/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt
+++ b/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt
@@ -103,14 +103,21 @@ class HomeViewModel @Inject constructor(
}
}
- fun putFilteringInfo(grade: String, workingPeriod: String, year: Int, month: Int) {
+ fun putFilteringInfo(
+ grade: String?,
+ workingPeriod: String?,
+ year: Int?,
+ month: Int?,
+ jobType: String
+ ) {
viewModelScope.launch {
homeRepository.putFilteringInfo(
ChangeFilteringRequestModel(
grade,
workingPeriod,
year,
- month
+ month,
+ jobType
)
).onSuccess {
getFilteringInfo()
diff --git a/feature/home/src/main/java/com/terning/feature/home/component/HomeFilteringBottomSheet.kt b/feature/home/src/main/java/com/terning/feature/home/component/HomeFilteringBottomSheet.kt
deleted file mode 100644
index 47d7df74..00000000
--- a/feature/home/src/main/java/com/terning/feature/home/component/HomeFilteringBottomSheet.kt
+++ /dev/null
@@ -1,270 +0,0 @@
-package com.terning.feature.home.component
-
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.wrapContentHeight
-import androidx.compose.foundation.lazy.grid.GridCells
-import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
-import androidx.compose.foundation.lazy.grid.itemsIndexed
-import androidx.compose.material3.Checkbox
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.HorizontalDivider
-import androidx.compose.material3.Text
-import androidx.compose.material3.rememberModalBottomSheetState
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableIntStateOf
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.dp
-import com.terning.core.designsystem.R
-import com.terning.core.designsystem.component.bottomsheet.TerningBasicBottomSheet
-import com.terning.core.designsystem.component.button.ChangeFilterButton
-import com.terning.core.designsystem.component.button.RoundButton
-import com.terning.core.designsystem.extension.currentMonth
-import com.terning.core.designsystem.extension.currentYear
-import com.terning.core.designsystem.theme.Black
-import com.terning.core.designsystem.theme.Grey200
-import com.terning.core.designsystem.theme.TerningTheme
-import com.terning.core.designsystem.type.Grade
-import com.terning.core.designsystem.type.WorkingPeriod
-import kotlinx.collections.immutable.toImmutableList
-import java.util.Calendar
-
-@OptIn(ExperimentalMaterial3Api::class)
-@Composable
-fun HomeFilteringBottomSheet(
- modifier: Modifier = Modifier,
- defaultGrade: Grade?,
- defaultWorkingPeriod: WorkingPeriod?,
- defaultStartYear: Int?,
- defaultStartMonth: Int?,
- onDismiss: () -> Unit,
- onChangeButtonClick: (String, String, Int, Int) -> Unit,
-) {
- val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
-
- var currentGrade by remember { mutableStateOf(defaultGrade) }
- var currentPeriod by remember { mutableStateOf(defaultWorkingPeriod) }
- var currentStartYear by remember {
- mutableIntStateOf(
- defaultStartYear ?: Calendar.getInstance().currentYear
- )
- }
- var currentStartMonth by remember {
- mutableIntStateOf(
- defaultStartMonth ?: Calendar.getInstance().currentMonth
- )
- }
-
- var isYearNull by remember { mutableStateOf(defaultStartYear != null) }
- var isMonthNull by remember { mutableStateOf(defaultStartMonth != null) }
-
- var isCheckBoxChecked by remember { mutableStateOf(false) }
-
- var isInitialNullState by remember { mutableStateOf(false) }
-
- val yearsList by remember(isYearNull) {
- mutableStateOf(
- if (isYearNull || isInitialNullState) years + NULL_DATE
- else years
- )
- }
- val monthsList by remember(isMonthNull) {
- mutableStateOf(
- if (isMonthNull || isInitialNullState) months + NULL_DATE
- else months
- )
- }
-
- TerningBasicBottomSheet(
- content = {
- Column(
- modifier = modifier
- .fillMaxWidth(),
- ) {
- Text(
- text = stringResource(id = R.string.change_filter_top_bar_title),
- style = TerningTheme.typography.title2,
- color = Black,
- modifier = Modifier
- .padding(horizontal = 24.dp)
- .padding(bottom = 16.dp),
- )
-
- HorizontalDivider(
- thickness = 1.dp,
- color = Grey200,
- modifier = Modifier
- .padding(horizontal = 24.dp),
- )
-
- ChangeFilteringTitleText(
- text = stringResource(id = R.string.change_filter_grade_title),
- modifier = Modifier
- .padding(top = 18.dp, bottom = 12.dp)
- .padding(horizontal = 24.dp)
- )
-
- ChangeFilteringRadioGroup(
- initOption = defaultGrade?.ordinal ?: -1,
- optionList = listOf(
- R.string.change_filter_grade_1,
- R.string.change_filter_grade_2,
- R.string.change_filter_grade_3,
- R.string.change_filter_grade_4,
- ),
- onButtonClick = { index ->
- currentGrade = Grade.entries[index]
- },
- modifier = Modifier
- .padding(horizontal = 24.dp),
- )
-
- ChangeFilteringTitleText(
- text = stringResource(id = R.string.change_filter_period_title),
- modifier = Modifier
- .padding(top = 32.dp, bottom = 12.dp)
- .padding(horizontal = 24.dp)
- )
-
- ChangeFilteringRadioGroup(
- initOption = defaultWorkingPeriod?.ordinal ?: -1,
- optionList = listOf(
- R.string.change_filter_period_1,
- R.string.change_filter_period_2,
- R.string.change_filter_period_3,
- ),
- onButtonClick = { index ->
- currentPeriod = WorkingPeriod.entries[index]
- },
- modifier = Modifier
- .padding(horizontal = 24.dp),
- )
-
- ChangeFilteringTitleText(
- text = stringResource(id = R.string.change_filter_start_work_title),
- modifier = Modifier
- .padding(top = 32.dp, bottom = 49.dp)
- .padding(horizontal = 24.dp)
- )
-
- //TODO: 아래는 임시 체크박스로, 추후 수정 부탁합니다!
- Checkbox(
- checked = isCheckBoxChecked,
- onCheckedChange = { isChecked ->
- if (isChecked) {
- isYearNull = true
- isMonthNull = true
- }
- isCheckBoxChecked = isChecked
- },
- modifier = Modifier.padding(start = 20.dp)
- )
-
- HomeYearMonthPicker(
- chosenYear = defaultStartYear,
- chosenMonth = defaultStartMonth,
- onYearChosen = { year, isInitialSelection ->
- if (year != null) {
- currentStartYear = year
- isCheckBoxChecked = false
- isYearNull = false
- isInitialNullState = isInitialSelection
- }
- },
- onMonthChosen = { month, isInitialSelection ->
- if (month != null) {
- currentStartMonth = month
- isCheckBoxChecked = false
- isMonthNull = false
- isInitialNullState = isInitialSelection
- }
- },
- isYearNull = isYearNull,
- isMonthNull = isMonthNull,
- yearsList = yearsList.toImmutableList(),
- monthsList = monthsList.toImmutableList(),
- isInitialNullState = isInitialNullState
- )
-
- RoundButton(
- style = TerningTheme.typography.button0,
- paddingVertical = 19.dp,
- text = R.string.change_filter_save,
- cornerRadius = 10.dp,
- modifier = Modifier
- .padding(horizontal = 24.dp)
- .padding(top = 51.dp),
- onButtonClick = {
- currentGrade?.let { grade ->
- currentPeriod?.let { workingPeriod ->
- onChangeButtonClick(
- grade.stringValue,
- workingPeriod.stringValue,
- currentStartYear,
- currentStartMonth,
- )
- }
- }
- },
- isEnabled = currentGrade != null && currentPeriod != null
- )
- }
- },
- onDismissRequest = onDismiss,
- sheetState = sheetState,
- )
-}
-
-@Composable
-fun ChangeFilteringTitleText(
- text: String,
- modifier: Modifier = Modifier,
-) {
- Text(
- text = text,
- style = TerningTheme.typography.title4,
- color = Black,
- modifier = modifier,
- )
-}
-
-@Composable
-fun ChangeFilteringRadioGroup(
- optionList: List,
- initOption: Int,
- onButtonClick: (Int) -> Unit,
- modifier: Modifier = Modifier,
-) {
- var selectedIndex by remember { mutableIntStateOf(initOption) }
-
- LazyVerticalGrid(
- columns = GridCells.Fixed(optionList.size),
- horizontalArrangement = Arrangement.spacedBy(13.dp),
- modifier = modifier
- .fillMaxWidth()
- .wrapContentHeight()
-
- ) {
- itemsIndexed(optionList) { index, option ->
- ChangeFilterButton(
- isSelected = selectedIndex == index,
- modifier = Modifier
- .wrapContentHeight(),
- text = option,
- cornerRadius = 10.dp,
- paddingVertical = 10.dp,
- onButtonClick = {
- selectedIndex = index
- onButtonClick(index)
- }
- )
- }
- }
-}
\ No newline at end of file
diff --git a/feature/home/src/main/java/com/terning/feature/home/component/HomeSortingButton.kt b/feature/home/src/main/java/com/terning/feature/home/component/HomeSortingButton.kt
new file mode 100644
index 00000000..15415de5
--- /dev/null
+++ b/feature/home/src/main/java/com/terning/feature/home/component/HomeSortingButton.kt
@@ -0,0 +1,62 @@
+package com.terning.feature.home.component
+
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.res.vectorResource
+import androidx.compose.ui.unit.dp
+import com.terning.core.designsystem.R
+import com.terning.core.designsystem.extension.noRippleClickable
+import com.terning.core.designsystem.theme.Grey350
+import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.core.designsystem.type.SortBy
+
+@Composable
+internal fun HomeSortingButton(
+ modifier: Modifier = Modifier,
+ sortBy: Int = 0,
+ onCLick: () -> Unit,
+) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = modifier
+ .border(
+ width = 1.dp,
+ color = Grey350,
+ shape = RoundedCornerShape(5.dp)
+ )
+ .noRippleClickable(onCLick),
+ ) {
+ Icon(
+ imageVector = ImageVector.vectorResource(id = R.drawable.ic_down_18),
+ contentDescription = stringResource(id = R.string.sort_button_description),
+ tint = Grey350,
+ modifier = Modifier
+ .padding(
+ start = 7.dp,
+ end = 6.dp,
+ top = 5.dp,
+ bottom = 5.dp,
+ )
+ .size(20.dp)
+ )
+ Text(
+ text = stringResource(
+ id = SortBy.entries[sortBy].sortBy
+ ),
+ style = TerningTheme.typography.button3,
+ color = Grey350,
+ modifier = Modifier
+ .padding(end = 11.dp)
+ )
+ }
+}
diff --git a/feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/HomeFilteringBottomSheet.kt b/feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/HomeFilteringBottomSheet.kt
new file mode 100644
index 00000000..e56e6e70
--- /dev/null
+++ b/feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/HomeFilteringBottomSheet.kt
@@ -0,0 +1,263 @@
+package com.terning.feature.home.component.bottomsheet
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.IntrinsicSize
+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.width
+import androidx.compose.foundation.pager.HorizontalPager
+import androidx.compose.foundation.pager.rememberPagerState
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.Text
+import androidx.compose.material3.rememberModalBottomSheetState
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+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
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.terning.core.designsystem.component.bottomsheet.TerningBasicBottomSheet
+import com.terning.core.designsystem.component.button.RoundButton
+import com.terning.core.designsystem.extension.noRippleClickable
+import com.terning.core.designsystem.theme.Black
+import com.terning.core.designsystem.theme.Grey200
+import com.terning.core.designsystem.theme.Grey300
+import com.terning.core.designsystem.theme.TerningMain
+import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.core.designsystem.type.Grade
+import com.terning.core.designsystem.type.JobType
+import com.terning.core.designsystem.type.WorkingPeriod
+import com.terning.domain.home.entity.HomeFilteringInfo
+import com.terning.feature.home.R
+import kotlinx.coroutines.launch
+import okhttp3.internal.toImmutableList
+
+private val filterType =
+ listOf(R.string.change_job_type_filter, R.string.change_plan_type_filter).toImmutableList()
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+internal fun HomeFilteringBottomSheet(
+ defaultFilteringInfo: HomeFilteringInfo,
+ onDismiss: () -> Unit,
+ onChangeButtonClick: (String?, String?, Int?, Int?, String) -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
+
+ var currentFilteringInfo by remember {
+ mutableStateOf(defaultFilteringInfo)
+ }
+ val pagerState = rememberPagerState { filterType.size }
+ val coroutineScope = rememberCoroutineScope()
+
+ val density = LocalDensity.current
+ var pageHeight by remember { mutableIntStateOf(0) }
+
+ LaunchedEffect(pagerState.currentPage) {
+ currentFilteringInfo = defaultFilteringInfo
+ }
+
+ GetPagerHeight(
+ onHeightMeasured = {
+ pageHeight = it
+ }
+ )
+
+ TerningBasicBottomSheet(
+ content = {
+ Column(
+ modifier = modifier
+ .fillMaxWidth(),
+ ) {
+ Text(
+ text = stringResource(id = R.string.change_filter_top_bar_title),
+ style = TerningTheme.typography.title2,
+ color = Black,
+ modifier = Modifier
+ .padding(horizontal = 24.dp)
+ .padding(bottom = 16.dp),
+ )
+
+ Row(
+ modifier = Modifier
+ .padding(horizontal = 23.dp),
+ verticalAlignment = Alignment.Bottom,
+ horizontalArrangement = Arrangement.spacedBy(28.dp),
+ ) {
+ filterType.forEachIndexed { index, option ->
+ TerningTab(
+ tabText = stringResource(id = option),
+ selected = pagerState.currentPage == index,
+ onTabClick = {
+ coroutineScope.launch {
+ pagerState.animateScrollToPage(index)
+ }
+ }
+ )
+ }
+ }
+
+ HorizontalDivider(
+ thickness = 1.dp,
+ color = Grey200,
+ modifier = Modifier
+ .padding(horizontal = 24.dp),
+ )
+
+ HorizontalPager(
+ state = pagerState,
+ beyondViewportPageCount = 1,
+ modifier = Modifier
+ .padding(top = 16.dp),
+ ) { currentPage ->
+ when (currentPage) {
+ 0 -> {
+ JobFilteringScreen(
+ initOption = JobType.fromString(currentFilteringInfo.jobType).ordinal,
+ onButtonClick = { jobType ->
+ currentFilteringInfo = currentFilteringInfo.copy(
+ jobType = jobType.stringValue
+ )
+ },
+ modifier = Modifier.height(with(density) { pageHeight.toDp() })
+ )
+ }
+
+ 1 -> {
+ PlanFilteringScreen(
+ currentFilteringInfo = currentFilteringInfo,
+ updateGrade = {
+ currentFilteringInfo = currentFilteringInfo.copy(
+ grade = if (it != null) {
+ Grade.entries[it].stringValue
+ } else null
+ )
+ },
+ updateWorkingPeriod = {
+ currentFilteringInfo = currentFilteringInfo.copy(
+ workingPeriod = if (it != null) {
+ WorkingPeriod.entries[it].stringValue
+ } else null
+ )
+ },
+ updateStartYear = {
+ currentFilteringInfo = currentFilteringInfo.copy(
+ startYear = it
+ )
+ },
+ updateStartMonth = {
+ currentFilteringInfo = currentFilteringInfo.copy(
+ startMonth = it
+ )
+ },
+ )
+ }
+ }
+ }
+
+ RoundButton(
+ style = TerningTheme.typography.button0,
+ paddingVertical = 19.dp,
+ text = R.string.change_filter_save,
+ cornerRadius = 10.dp,
+ modifier = Modifier
+ .padding(horizontal = 24.dp),
+ onButtonClick = {
+ with(currentFilteringInfo) {
+ onChangeButtonClick(
+ grade,
+ workingPeriod,
+ startYear,
+ startMonth,
+ jobType
+ )
+ }
+ },
+ isEnabled = checkButtonEnable(currentFilteringInfo = currentFilteringInfo)
+ )
+ }
+
+ },
+ onDismissRequest = onDismiss,
+ sheetState = sheetState,
+ )
+}
+
+@Composable
+fun ChangeFilteringTitleText(
+ text: String,
+ modifier: Modifier = Modifier,
+) {
+ Text(
+ text = text,
+ style = TerningTheme.typography.title4,
+ color = Black,
+ modifier = modifier,
+ )
+}
+
+@Composable
+fun TerningTab(
+ tabText: String,
+ selected: Boolean,
+ onTabClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ Column(
+ modifier = modifier
+ .width(IntrinsicSize.Max)
+ .noRippleClickable { onTabClick() },
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center,
+ ) {
+ Text(
+ text = tabText,
+ style = TerningTheme.typography.title4,
+ color = if (selected) TerningMain else Grey300,
+ modifier = Modifier
+ .padding(bottom = 7.dp),
+ )
+
+ Spacer(
+ modifier = Modifier
+ .height(4.dp)
+ .fillMaxWidth()
+ .background(if (selected) TerningMain else Color.Transparent)
+ )
+ }
+}
+
+private fun checkButtonEnable(currentFilteringInfo: HomeFilteringInfo): Boolean =
+ with(currentFilteringInfo) {
+ listOf(grade, workingPeriod, startYear, startMonth).all { it == null || it == 0 } ||
+ listOf(grade, workingPeriod, startYear, startMonth).none { it == null || it == 0 }
+ }
+
+@Composable
+private fun GetPagerHeight(
+ onHeightMeasured: (Int) -> Unit,
+) {
+ PlanFilteringScreen(
+ currentFilteringInfo = HomeFilteringInfo(null, null, null, null, "total"),
+ modifier = Modifier
+ .onGloballyPositioned {
+ onHeightMeasured(it.size.height)
+ }
+ )
+}
\ No newline at end of file
diff --git a/feature/home/src/main/java/com/terning/feature/home/component/HomeYearMonthPicker.kt b/feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/HomeYearMonthPicker.kt
similarity index 93%
rename from feature/home/src/main/java/com/terning/feature/home/component/HomeYearMonthPicker.kt
rename to feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/HomeYearMonthPicker.kt
index d1f613ea..ff588aa2 100644
--- a/feature/home/src/main/java/com/terning/feature/home/component/HomeYearMonthPicker.kt
+++ b/feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/HomeYearMonthPicker.kt
@@ -1,4 +1,4 @@
-package com.terning.feature.home.component
+package com.terning.feature.home.component.bottomsheet
import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
import androidx.compose.foundation.layout.Arrangement
@@ -52,11 +52,10 @@ class PickerState {
}
@Composable
-fun rememberPickerState() = remember { PickerState() }
+private fun rememberPickerState() = remember { PickerState() }
@Composable
-fun HomeYearMonthPicker(
- modifier: Modifier = Modifier,
+internal fun HomeYearMonthPicker(
chosenYear: Int?,
chosenMonth: Int?,
onYearChosen: (Int?, Boolean) -> Unit,
@@ -65,7 +64,8 @@ fun HomeYearMonthPicker(
isMonthNull: Boolean,
yearsList: ImmutableList,
monthsList: ImmutableList,
- isInitialNullState: Boolean
+ isInitialNullState: Boolean,
+ modifier: Modifier = Modifier,
) {
val yearPickerState = rememberPickerState()
val monthPickerState = rememberPickerState()
@@ -74,10 +74,10 @@ fun HomeYearMonthPicker(
val startYearIndex =
if (isYearNull) yearsList.lastIndex else yearsList.indexOf("${chosenYear ?: "-"}년")
- .takeIf { it >= 0 } ?: 0
+ .takeIf { it >= 0 } ?: yearsList.lastIndex
val startMonthIndex =
if (isMonthNull) monthsList.lastIndex else monthsList.indexOf("${chosenMonth ?: "-"}월")
- .takeIf { it >= 0 } ?: 0
+ .takeIf { it >= 0 } ?: monthsList.lastIndex
Row(
modifier = modifier
@@ -116,7 +116,7 @@ fun HomeYearMonthPicker(
}
@Composable
-fun DatePicker(
+private fun DatePicker(
items: ImmutableList,
modifier: Modifier = Modifier,
pickerState: PickerState = rememberPickerState(),
@@ -135,6 +135,12 @@ fun DatePicker(
if (itemHeightPixel > 0 && startIndex >= 0) scrollState.scrollToItem(startIndex)
}
+ val savedIndex by remember { mutableIntStateOf(startIndex) }
+
+ LaunchedEffect(itemHeightPixel, savedIndex) {
+ scrollState.scrollToItem(savedIndex)
+ }
+
LaunchedEffect(scrollState) {
snapshotFlow { scrollState.firstVisibleItemIndex }
.map { index ->
@@ -196,7 +202,7 @@ fun DatePicker(
}
@Composable
-fun DatePickerContent(
+private fun DatePickerContent(
color: Color,
text: String,
modifier: Modifier = Modifier,
diff --git a/feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/JobFilteringScreen.kt b/feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/JobFilteringScreen.kt
new file mode 100644
index 00000000..03f24343
--- /dev/null
+++ b/feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/JobFilteringScreen.kt
@@ -0,0 +1,102 @@
+package com.terning.feature.home.component.bottomsheet
+
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
+import androidx.compose.foundation.lazy.grid.itemsIndexed
+import androidx.compose.foundation.shape.RoundedCornerShape
+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.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.res.vectorResource
+import androidx.compose.ui.unit.dp
+import com.terning.core.designsystem.extension.noRippleClickable
+import com.terning.core.designsystem.theme.Grey200
+import com.terning.core.designsystem.theme.Grey300
+import com.terning.core.designsystem.theme.Grey350
+import com.terning.core.designsystem.theme.TerningMain
+import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.core.designsystem.type.JobType
+
+@Composable
+internal fun JobFilteringScreen(
+ initOption: Int,
+ onButtonClick: (JobType) -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ var selectedIndex by remember { mutableIntStateOf(initOption) }
+
+ LazyVerticalGrid(
+ columns = GridCells.Fixed(3),
+ horizontalArrangement = Arrangement.spacedBy(10.dp),
+ verticalArrangement = Arrangement.spacedBy(12.dp),
+ modifier = modifier
+ .fillMaxWidth()
+ .wrapContentHeight()
+ .padding(bottom = 60.dp, start = 23.dp, end = 23.dp),
+
+ ) {
+ itemsIndexed(JobType.entries) { index, option ->
+ JobTypeItem(
+ jobType = option,
+ onButtonClick = {
+ selectedIndex = index
+ onButtonClick(option)
+ },
+ isSelected = selectedIndex == index
+ )
+ }
+ }
+}
+
+@Composable
+private fun JobTypeItem(
+ jobType: JobType,
+ isSelected: Boolean,
+ onButtonClick: (JobType) -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = modifier
+ .border(
+ width = 1.dp,
+ color = if (isSelected) TerningMain else Grey200,
+ shape = RoundedCornerShape(10.dp)
+ )
+ .noRippleClickable { onButtonClick(jobType) }
+ .padding(
+ top = 31.dp,
+ bottom = 33.dp,
+ start = 27.dp,
+ end = 26.dp
+ ),
+ ) {
+ Icon(
+ imageVector = ImageVector.vectorResource(id = jobType.drawableResId),
+ contentDescription = jobType.stringValue,
+ tint = if (isSelected) TerningMain else Grey300
+ )
+
+ Text(
+ text = stringResource(id = jobType.stringResId),
+ style = TerningTheme.typography.body6,
+ color = if (isSelected) TerningMain else Grey350,
+ modifier = Modifier
+ .padding(top = 7.dp)
+ )
+ }
+}
\ No newline at end of file
diff --git a/feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/PlanFilteringScreen.kt b/feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/PlanFilteringScreen.kt
new file mode 100644
index 00000000..8f3eca20
--- /dev/null
+++ b/feature/home/src/main/java/com/terning/feature/home/component/bottomsheet/PlanFilteringScreen.kt
@@ -0,0 +1,242 @@
+package com.terning.feature.home.component.bottomsheet
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
+import androidx.compose.foundation.lazy.grid.itemsIndexed
+import androidx.compose.material3.Checkbox
+import androidx.compose.material3.CheckboxDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.LocalMinimumInteractiveComponentEnforcement
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.terning.core.designsystem.component.button.ChangeFilterButton
+import com.terning.core.designsystem.theme.Grey300
+import com.terning.core.designsystem.theme.TerningMain
+import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.core.designsystem.theme.White
+import com.terning.core.designsystem.type.Grade
+import com.terning.core.designsystem.type.WorkingPeriod
+import com.terning.core.designsystem.util.NoRippleInteractionSource
+import com.terning.domain.home.entity.HomeFilteringInfo
+import com.terning.feature.home.R
+import kotlinx.collections.immutable.ImmutableList
+import kotlinx.collections.immutable.toImmutableList
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+internal fun PlanFilteringScreen(
+ currentFilteringInfo: HomeFilteringInfo,
+ modifier: Modifier = Modifier,
+ updateGrade: (Int?) -> Unit = {},
+ updateWorkingPeriod: (Int?) -> Unit = {},
+ updateStartYear: (Int?) -> Unit = {},
+ updateStartMonth: (Int?) -> Unit = {},
+) {
+ var isYearNull by remember { mutableStateOf(currentFilteringInfo.startYear == 0 || currentFilteringInfo.startYear == null) }
+ var isMonthNull by remember { mutableStateOf(currentFilteringInfo.startMonth == 0 || currentFilteringInfo.startMonth == null) }
+
+ var isCheckBoxChecked by remember { mutableStateOf(false) }
+
+ var isInitialNullState by remember { mutableStateOf(false) }
+
+ val yearsList by remember(isYearNull) {
+ mutableStateOf(
+ if (isYearNull || isInitialNullState) years + NULL_DATE
+ else years
+ )
+ }
+ val monthsList by remember(isMonthNull) {
+ mutableStateOf(
+ if (isMonthNull || isInitialNullState) months + NULL_DATE
+ else months
+ )
+ }
+
+ Column(
+ modifier = modifier
+ ) {
+ ChangeFilteringTitleText(
+ text = stringResource(id = R.string.change_filter_grade_title),
+ modifier = Modifier
+ .padding(
+ start = 23.dp,
+ end = 23.dp,
+ bottom = 12.dp
+ )
+ )
+
+ ChangePlanFilteringRadioGroup(
+ initOption = currentFilteringInfo.grade?.let { Grade.fromString(it).ordinal } ?: -1,
+ isCheckBoxChecked = isCheckBoxChecked,
+ optionList = listOf(
+ R.string.change_filter_grade_1,
+ R.string.change_filter_grade_2,
+ R.string.change_filter_grade_3,
+ R.string.change_filter_grade_4,
+ ).toImmutableList(),
+ onButtonClick = {
+ updateGrade(it)
+ isCheckBoxChecked = false
+ },
+ columns = 4,
+ modifier = Modifier
+ .padding(horizontal = 23.dp),
+ )
+
+ ChangeFilteringTitleText(
+ text = stringResource(id = R.string.change_filter_period_title),
+ modifier = Modifier
+ .padding(top = 24.dp, bottom = 12.dp)
+ .padding(horizontal = 24.dp)
+ )
+
+ ChangePlanFilteringRadioGroup(
+ initOption = currentFilteringInfo.workingPeriod?.let { WorkingPeriod.fromString(it).ordinal }
+ ?: -1,
+ isCheckBoxChecked = isCheckBoxChecked,
+ optionList = listOf(
+ R.string.change_filter_period_1,
+ R.string.change_filter_period_2,
+ R.string.change_filter_period_3,
+ ).toImmutableList(),
+ onButtonClick = {
+ updateWorkingPeriod(it)
+ isCheckBoxChecked = false
+ },
+ modifier = Modifier
+ .padding(horizontal = 23.dp),
+ )
+
+ ChangeFilteringTitleText(
+ text = stringResource(id = R.string.change_filter_start_work_title),
+ modifier = Modifier
+ .padding(24.dp)
+ )
+
+ HomeYearMonthPicker(
+ chosenYear = currentFilteringInfo.startYear,
+ chosenMonth = currentFilteringInfo.startMonth,
+ onYearChosen = { year, isInitialSelection ->
+ updateStartYear(year)
+ if (year != null) {
+ isCheckBoxChecked = false
+ isYearNull = false
+ isInitialNullState = isInitialSelection
+ }
+ },
+ onMonthChosen = { month, isInitialSelection ->
+ updateStartMonth(month)
+ if (month != null) {
+ isCheckBoxChecked = false
+ isMonthNull = false
+ isInitialNullState = isInitialSelection
+ }
+ },
+ isYearNull = isYearNull,
+ isMonthNull = isMonthNull,
+ yearsList = yearsList.toImmutableList(),
+ monthsList = monthsList.toImmutableList(),
+ isInitialNullState = isInitialNullState
+ )
+
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.End,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ bottom = 13.dp,
+ top = 26.dp,
+ end = 24.dp
+ ),
+ ) {
+ CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
+ Checkbox(
+ checked = isCheckBoxChecked,
+ onCheckedChange = { isChecked ->
+ if (isChecked) {
+ isYearNull = true
+ isMonthNull = true
+ updateGrade(null)
+ updateWorkingPeriod(null)
+ updateStartYear(null)
+ updateStartMonth(null)
+ }
+ isCheckBoxChecked = isChecked
+ },
+ colors = CheckboxDefaults.colors(
+ checkedColor = TerningMain,
+ uncheckedColor = Grey300,
+ checkmarkColor = White,
+ ),
+ interactionSource = NoRippleInteractionSource
+ )
+ }
+
+ Text(
+ text = stringResource(id = R.string.intern_with_no_plan_filter),
+ style = TerningTheme.typography.button3,
+ color = Grey300,
+ modifier = Modifier.padding(start = 6.dp),
+ )
+ }
+ }
+}
+
+@Composable
+private fun ChangePlanFilteringRadioGroup(
+ optionList: ImmutableList,
+ initOption: Int,
+ isCheckBoxChecked: Boolean,
+ onButtonClick: (Int) -> Unit,
+ modifier: Modifier = Modifier,
+ columns: Int = 3,
+) {
+ var selectedIndex by remember { mutableIntStateOf(initOption) }
+
+ LaunchedEffect(isCheckBoxChecked) {
+ if (isCheckBoxChecked) {
+ selectedIndex = -1
+ }
+ }
+
+ LazyVerticalGrid(
+ columns = GridCells.Fixed(columns),
+ horizontalArrangement = Arrangement.spacedBy(13.dp),
+ modifier = modifier
+ .fillMaxWidth()
+ .wrapContentHeight()
+ ) {
+ itemsIndexed(optionList) { index, option ->
+ ChangeFilterButton(
+ isSelected = selectedIndex == index && !isCheckBoxChecked,
+ modifier = Modifier
+ .wrapContentHeight(),
+ text = option,
+ cornerRadius = 10.dp,
+ paddingVertical = 10.dp,
+ onButtonClick = {
+ selectedIndex = index
+ onButtonClick(index)
+ }
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature/home/src/main/res/values/strings.xml b/feature/home/src/main/res/values/strings.xml
index 02b22856..390dfff0 100644
--- a/feature/home/src/main/res/values/strings.xml
+++ b/feature/home/src/main/res/values/strings.xml
@@ -13,9 +13,6 @@
%s년 %s월
아직 채용중인 인턴 공고가 없어요!\n새로운 공고가 올라오면 보여드릴게요
인턴 공고가 없어요!
-
- 지금 공고 필터링을 설정하고\n내 계획에 딱 맞는 대학생 인턴 공고를 추천받아보세요!
-
총
개
설정된 필터링 정보가 없어요
@@ -24,4 +21,20 @@
-
오늘 마감인 공고가 없어요
지원마감
+
+ 필터링
+ 직무 카테고리
+ 계획
+ 재학 상태
+ 저장하기
+ 1학년
+ 2학년
+ 3학년
+ 4학년
+ 희망 근무 기간
+ 1 ~ 3개월
+ 4 ~ 6개월
+ 7개월 이상
+ 근무 시작 시기
+ 계획 필터링 없이 모든 공고 보기