diff --git a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/SortBy.kt b/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/SortBy.kt deleted file mode 100644 index 3d6ce0916..000000000 --- a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/SortBy.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.terning.core.designsystem.component.bottomsheet - -import androidx.annotation.StringRes -import com.terning.core.R - -enum class SortBy(@StringRes val type: Int) { - EARLIEST(R.string.sort_by_earliest), - SHORTEST(R.string.sort_by_shortest), - LONGEST(R.string.sort_by_longest), - SCRAP(R.string.sort_by_scrap), - VIEW_COUNT(R.string.sort_by_view_count), -} \ No newline at end of file diff --git a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/SortingBottomSheet.kt b/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/SortingBottomSheet.kt index 49ae29b21..806fefee3 100644 --- a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/SortingBottomSheet.kt +++ b/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/SortingBottomSheet.kt @@ -26,6 +26,7 @@ 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.extension.noRippleClickable +import com.terning.core.type.SortBy import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) @@ -64,7 +65,7 @@ fun SortingBottomSheet( ) { items(sortByCount) { sortIndex -> Text( - text = stringResource(id = SortBy.entries[sortIndex].type), + text = stringResource(id = SortBy.entries[sortIndex].sortBy), style = TerningTheme.typography.button3, color = if (currentSortBy == sortIndex) TerningMain else Grey400, textAlign = TextAlign.Start, diff --git a/core/src/main/java/com/terning/core/designsystem/component/button/ChangeFilterButton.kt b/core/src/main/java/com/terning/core/designsystem/component/button/ChangeFilterButton.kt index 3aeadcc0d..dbef1eb85 100644 --- a/core/src/main/java/com/terning/core/designsystem/component/button/ChangeFilterButton.kt +++ b/core/src/main/java/com/terning/core/designsystem/component/button/ChangeFilterButton.kt @@ -21,10 +21,11 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.terning.core.designsystem.theme.Grey400 +import com.terning.core.designsystem.theme.Grey150 +import com.terning.core.designsystem.theme.Grey200 +import com.terning.core.designsystem.theme.Grey375 +import com.terning.core.designsystem.theme.Grey50 import com.terning.core.designsystem.theme.TerningMain -import com.terning.core.designsystem.theme.TerningSub1 -import com.terning.core.designsystem.theme.TerningSub5 import com.terning.core.designsystem.theme.TerningTheme import com.terning.core.designsystem.theme.White import com.terning.core.util.NoRippleTheme @@ -42,16 +43,16 @@ fun ChangeFilterButton( val isPressed by interactionSource.collectIsPressedAsState() val backgroundColor = when { !isSelected && !isPressed -> White - !isSelected && isPressed -> TerningSub5 - else -> TerningMain + !isSelected && isPressed -> Grey50 + else -> White } val textColor = when { - !isSelected -> Grey400 - else -> White + !isSelected -> Grey375 + else -> TerningMain } val borderColor = when { - !isSelected && !isPressed -> TerningMain - !isSelected && isPressed -> TerningSub1 + !isSelected && !isPressed -> Grey150 + !isSelected && isPressed -> Grey200 else -> TerningMain } diff --git a/core/src/main/java/com/terning/core/designsystem/component/button/SortingButton.kt b/core/src/main/java/com/terning/core/designsystem/component/button/SortingButton.kt index 27693a251..162e19b33 100644 --- a/core/src/main/java/com/terning/core/designsystem/component/button/SortingButton.kt +++ b/core/src/main/java/com/terning/core/designsystem/component/button/SortingButton.kt @@ -10,40 +10,43 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.terning.core.R -import com.terning.core.designsystem.component.bottomsheet.SortBy +import com.terning.core.type.SortBy import com.terning.core.designsystem.theme.Black import com.terning.core.designsystem.theme.TerningTheme import com.terning.core.extension.noRippleClickable @Composable fun SortingButton( - sortBy: Int = 0, modifier: Modifier = Modifier, + sortBy: Int = 0, onCLick: () -> Unit, ) { Row( modifier = modifier - .noRippleClickable { onCLick() } + .noRippleClickable(onCLick), ) { Text( text = stringResource( - id = SortBy.entries[sortBy].type + id = SortBy.entries[sortBy].sortBy ), style = TerningTheme.typography.button3, color = Black, - modifier = modifier + modifier = Modifier .padding( top = 6.dp, - bottom = 5.dp, - start = 12.dp, + bottom = 6.dp, ) ) Image( painter = painterResource(id = R.drawable.ic_down_18), contentDescription = stringResource(id = R.string.sort_button_description), - modifier = modifier - .padding(vertical = 5.dp) - .padding(end = 2.dp) + modifier = Modifier + .padding( + start = 2.dp, + end = 2.dp, + top = 6.dp, + bottom = 4.dp, + ) ) } } diff --git a/core/src/main/java/com/terning/core/designsystem/theme/Color.kt b/core/src/main/java/com/terning/core/designsystem/theme/Color.kt index 38e375622..69d24b9ff 100644 --- a/core/src/main/java/com/terning/core/designsystem/theme/Color.kt +++ b/core/src/main/java/com/terning/core/designsystem/theme/Color.kt @@ -4,6 +4,7 @@ import androidx.compose.ui.graphics.Color // Grey Scale val White = Color(0xFFFFFFFF) +val Grey50 = Color(0xFFFCFCFC) val Grey100 = Color(0xFFF5F5F5) val Grey150 = Color(0xFFE9E9E9) val Grey200 = Color(0xFFDDDDDD) diff --git a/core/src/main/java/com/terning/core/type/Grade.kt b/core/src/main/java/com/terning/core/type/Grade.kt new file mode 100644 index 000000000..99fef5432 --- /dev/null +++ b/core/src/main/java/com/terning/core/type/Grade.kt @@ -0,0 +1,24 @@ +package com.terning.core.type + +import androidx.annotation.StringRes +import com.terning.core.R + +enum class Grade( + val stringValue: String, + @StringRes val stringResId: Int, +) { + FRESHMAN("freshman", R.string.change_filter_grade_1), + SOPHOMORE("sophomore", R.string.change_filter_grade_2), + JUNIOR("junior", R.string.change_filter_grade_3), + SENIOR("senior", R.string.change_filter_grade_4); + + companion object { + fun fromString(value: String?): Grade = when (value) { + "freshman" -> FRESHMAN + "sophomore" -> SOPHOMORE + "junior" -> JUNIOR + "senior" -> SENIOR + else -> FRESHMAN + } + } +} \ No newline at end of file diff --git a/core/src/main/java/com/terning/core/type/SortBy.kt b/core/src/main/java/com/terning/core/type/SortBy.kt new file mode 100644 index 000000000..d0a8411ec --- /dev/null +++ b/core/src/main/java/com/terning/core/type/SortBy.kt @@ -0,0 +1,15 @@ +package com.terning.core.type + +import androidx.annotation.StringRes +import com.terning.core.R + +enum class SortBy( + @StringRes val sortBy: Int, + val type: String, +) { + EARLIEST(R.string.sort_by_earliest, "deadlineSoon"), + SHORTEST(R.string.sort_by_shortest, "shortestDuration"), + LONGEST(R.string.sort_by_longest, "longestDuration"), + SCRAP(R.string.sort_by_scrap, "mostScrapped"), + VIEW_COUNT(R.string.sort_by_view_count, "mostViewed"), +} diff --git a/core/src/main/java/com/terning/core/type/WorkingPeriod.kt b/core/src/main/java/com/terning/core/type/WorkingPeriod.kt new file mode 100644 index 000000000..d7a7328c8 --- /dev/null +++ b/core/src/main/java/com/terning/core/type/WorkingPeriod.kt @@ -0,0 +1,22 @@ +package com.terning.core.type + +import androidx.annotation.StringRes +import com.terning.core.R + +enum class WorkingPeriod( + val stringValue: String, + @StringRes val stringResId: Int, +) { + SHORT("short", R.string.change_filter_period_1), + MIDDLE("middle", R.string.change_filter_period_2), + LONG("long", R.string.change_filter_period_3); + + companion object { + fun fromString(value: String?): WorkingPeriod = when (value) { + "short" -> SHORT + "middle" -> MIDDLE + "long" -> LONG + else -> SHORT + } + } +} \ No newline at end of file diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 2a3dd454b..3237f106a 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -67,4 +67,18 @@ 사용 가능한 이름이에요 이름은 12자리 이내로 설정해 주세요 + + 필터링 재설정 + 재학 상태 + 저장하기 + 1학년 + 2학년 + 3학년 + 4학년 + 희망 근무 기간 + 1개월 ~ 3개월 + 4개월 ~ 6개월 + 7개월 이상 + 근무 시작 시기 + \ No newline at end of file diff --git a/data/src/main/java/com/terning/data/datasource/HomeDataSource.kt b/data/src/main/java/com/terning/data/datasource/HomeDataSource.kt index 97b10b6d3..61c101e42 100644 --- a/data/src/main/java/com/terning/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/terning/data/datasource/HomeDataSource.kt @@ -5,16 +5,16 @@ import com.terning.data.dto.NonDataBaseResponse import com.terning.data.dto.request.ChangeFilterRequestDto import com.terning.data.dto.response.HomeFilteringInfoResponseDto import com.terning.data.dto.response.HomeRecommendInternResponseDto -import com.terning.data.dto.response.HomeTodayInternResponseDto +import com.terning.data.dto.response.HomeUpcomingInternResponseDto interface HomeDataSource { - suspend fun getTodayIntern(): BaseResponse> + suspend fun getUpcomingIntern(): BaseResponse> suspend fun getRecommendIntern( sortBy: String, startYear: Int, startMonth: Int - ): BaseResponse> + ): BaseResponse suspend fun getFilteringInfo(): BaseResponse diff --git a/data/src/main/java/com/terning/data/datasourceimpl/HomeDataSourceImpl.kt b/data/src/main/java/com/terning/data/datasourceimpl/HomeDataSourceImpl.kt index 9c5416942..9e859e56f 100644 --- a/data/src/main/java/com/terning/data/datasourceimpl/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/terning/data/datasourceimpl/HomeDataSourceImpl.kt @@ -6,21 +6,21 @@ import com.terning.data.dto.NonDataBaseResponse import com.terning.data.dto.request.ChangeFilterRequestDto import com.terning.data.dto.response.HomeFilteringInfoResponseDto import com.terning.data.dto.response.HomeRecommendInternResponseDto -import com.terning.data.dto.response.HomeTodayInternResponseDto +import com.terning.data.dto.response.HomeUpcomingInternResponseDto import com.terning.data.service.HomeService import javax.inject.Inject class HomeDataSourceImpl @Inject constructor( private val homeService: HomeService, ) : HomeDataSource { - override suspend fun getTodayIntern(): BaseResponse> = - homeService.getHomeTodayIntern() + override suspend fun getUpcomingIntern(): BaseResponse> = + homeService.getHomeUpcomingIntern() override suspend fun getRecommendIntern( sortBy: String, startYear: Int, startMonth: Int - ): BaseResponse> = + ): BaseResponse = homeService.getRecommendIntern( sortBy = sortBy, startYear = startYear, @@ -30,6 +30,6 @@ class HomeDataSourceImpl @Inject constructor( override suspend fun getFilteringInfo(): BaseResponse = homeService.getFilteringInfo() - override suspend fun putFilteringInfo(request: ChangeFilterRequestDto): NonDataBaseResponse = - homeService.putFilteringInfo(request) + override suspend fun putFilteringInfo(changeFilterRequestDto: ChangeFilterRequestDto): NonDataBaseResponse = + homeService.putFilteringInfo(changeFilterRequestDto) } \ No newline at end of file diff --git a/data/src/main/java/com/terning/data/dto/response/HomeRecommendInternResponseDto.kt b/data/src/main/java/com/terning/data/dto/response/HomeRecommendInternResponseDto.kt index c8f8e8671..6e28c8be2 100644 --- a/data/src/main/java/com/terning/data/dto/response/HomeRecommendInternResponseDto.kt +++ b/data/src/main/java/com/terning/data/dto/response/HomeRecommendInternResponseDto.kt @@ -5,22 +5,30 @@ import kotlinx.serialization.Serializable @Serializable data class HomeRecommendInternResponseDto( - @SerialName("scrapId") - val scrapId: Long?, - @SerialName("intershipAnnouncementId") - val internshipAnnouncementId: Long, - @SerialName("title") - val title: String, - @SerialName("dDay") - val dDay: String, - @SerialName("deadline") - val deadline: String, - @SerialName("workingPeriod") - val workingPeriod: String, - @SerialName("startYearMonth") - val startYearMonth: String, - @SerialName("companyImage") - val companyImage: String, - @SerialName("isScrapped") - val isScrapped: Boolean, -) + @SerialName("totalCount") + val totalCount: Int, + @SerialName("result") + val result: List +) { + @Serializable + data class Result( + @SerialName("intershipAnnouncementId") + val internshipAnnouncementId: Long, + @SerialName("title") + val title: String, + @SerialName("dDay") + val dDay: String, + @SerialName("deadline") + val deadline: String, + @SerialName("workingPeriod") + val workingPeriod: String, + @SerialName("startYearMonth") + val startYearMonth: String, + @SerialName("companyImage") + val companyImage: String, + @SerialName("isScrapped") + val isScrapped: Boolean, + @SerialName("color") + val color: String?, + ) +} diff --git a/data/src/main/java/com/terning/data/dto/response/HomeTodayInternResponseDto.kt b/data/src/main/java/com/terning/data/dto/response/HomeUpcomingInternResponseDto.kt similarity index 85% rename from data/src/main/java/com/terning/data/dto/response/HomeTodayInternResponseDto.kt rename to data/src/main/java/com/terning/data/dto/response/HomeUpcomingInternResponseDto.kt index 33283ae00..25ed289d1 100644 --- a/data/src/main/java/com/terning/data/dto/response/HomeTodayInternResponseDto.kt +++ b/data/src/main/java/com/terning/data/dto/response/HomeUpcomingInternResponseDto.kt @@ -4,9 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable -data class HomeTodayInternResponseDto( - @SerialName("scrapId") - val scrapId: Long, +data class HomeUpcomingInternResponseDto( @SerialName("internshipAnnouncementId") val internshipAnnouncementId: Long, @SerialName("companyImage") @@ -19,9 +17,10 @@ data class HomeTodayInternResponseDto( val deadline: String, @SerialName("workingPeriod") val workingPeriod: String, + @SerialName("isScrapped") + val isScrapped: Boolean, @SerialName("color") val color: String, @SerialName("startYearMonth") val startYearMonth: String, - ) \ No newline at end of file diff --git a/data/src/main/java/com/terning/data/mapper/home/HomeRecommendInternMapper.kt b/data/src/main/java/com/terning/data/mapper/home/HomeRecommendInternMapper.kt index 6e505189c..96a45724d 100644 --- a/data/src/main/java/com/terning/data/mapper/home/HomeRecommendInternMapper.kt +++ b/data/src/main/java/com/terning/data/mapper/home/HomeRecommendInternMapper.kt @@ -5,7 +5,14 @@ import com.terning.domain.entity.home.HomeRecommendIntern fun HomeRecommendInternResponseDto.toHomeRecommendInternList(): HomeRecommendIntern = HomeRecommendIntern( - scrapId = this.scrapId, + totalCount = this.totalCount, + homeRecommendInternDetail = this.result.map { + it.toHomeRecommendInternDetail() + } + ) + +fun HomeRecommendInternResponseDto.Result.toHomeRecommendInternDetail(): HomeRecommendIntern.HomeRecommendInternDetail = + HomeRecommendIntern.HomeRecommendInternDetail( internshipAnnouncementId = this.internshipAnnouncementId, title = this.title, dDay = this.dDay, @@ -14,4 +21,5 @@ fun HomeRecommendInternResponseDto.toHomeRecommendInternList(): HomeRecommendInt startYearMonth = this.startYearMonth, companyImage = this.companyImage, isScrapped = this.isScrapped, - ) + color = this.color, + ) \ No newline at end of file diff --git a/data/src/main/java/com/terning/data/mapper/home/HomeTodayInternMapper.kt b/data/src/main/java/com/terning/data/mapper/home/HomeUpcomingInternMapper.kt similarity index 57% rename from data/src/main/java/com/terning/data/mapper/home/HomeTodayInternMapper.kt rename to data/src/main/java/com/terning/data/mapper/home/HomeUpcomingInternMapper.kt index 762354301..3521339f9 100644 --- a/data/src/main/java/com/terning/data/mapper/home/HomeTodayInternMapper.kt +++ b/data/src/main/java/com/terning/data/mapper/home/HomeUpcomingInternMapper.kt @@ -1,17 +1,17 @@ package com.terning.data.mapper.home -import com.terning.data.dto.response.HomeTodayInternResponseDto -import com.terning.domain.entity.home.HomeTodayIntern +import com.terning.data.dto.response.HomeUpcomingInternResponseDto +import com.terning.domain.entity.home.HomeUpcomingIntern -fun HomeTodayInternResponseDto.toHomeTodayInternList(): HomeTodayIntern = - HomeTodayIntern( - scrapId = this.scrapId, +fun HomeUpcomingInternResponseDto.toHomeUpcomingInternList(): HomeUpcomingIntern = + HomeUpcomingIntern( internshipAnnouncementId = this.internshipAnnouncementId, companyImage = this.companyImage, title = this.title, dDay = this.dDay, deadline = this.deadline, workingPeriod = this.workingPeriod, + isScrapped = this.isScrapped, startYearMonth = this.startYearMonth, color = this.color, ) \ No newline at end of file diff --git a/data/src/main/java/com/terning/data/repositoryimpl/HomeRepositoryImpl.kt b/data/src/main/java/com/terning/data/repositoryimpl/HomeRepositoryImpl.kt index 25dc6cc11..f8247399f 100644 --- a/data/src/main/java/com/terning/data/repositoryimpl/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/terning/data/repositoryimpl/HomeRepositoryImpl.kt @@ -4,10 +4,10 @@ import com.terning.data.datasource.HomeDataSource import com.terning.data.dto.request.toChangeFilterRequestDto import com.terning.data.mapper.home.toHomeFilteringInfo import com.terning.data.mapper.home.toHomeRecommendInternList -import com.terning.data.mapper.home.toHomeTodayInternList +import com.terning.data.mapper.home.toHomeUpcomingInternList import com.terning.domain.entity.home.HomeFilteringInfo import com.terning.domain.entity.home.HomeRecommendIntern -import com.terning.domain.entity.home.HomeTodayIntern +import com.terning.domain.entity.home.HomeUpcomingIntern import com.terning.domain.entity.request.ChangeFilteringRequestModel import com.terning.domain.repository.HomeRepository import javax.inject.Inject @@ -15,10 +15,10 @@ import javax.inject.Inject class HomeRepositoryImpl @Inject constructor( private val homeDataSource: HomeDataSource, ) : HomeRepository { - override suspend fun getHomeTodayInternList(): Result> = + override suspend fun getHomeUpcomingInternList(): Result> = runCatching { - homeDataSource.getTodayIntern().result.map { homeTodayInternResponseDto -> - homeTodayInternResponseDto.toHomeTodayInternList() + homeDataSource.getUpcomingIntern().result.map { homeTodayInternResponseDto -> + homeTodayInternResponseDto.toHomeUpcomingInternList() } } @@ -26,15 +26,13 @@ class HomeRepositoryImpl @Inject constructor( sortBy: String, startYear: Int, startMonth: Int - ): Result> = + ): Result = runCatching { homeDataSource.getRecommendIntern( sortBy = sortBy, startYear = startYear, startMonth = startMonth - ).result.map { homeRecommendInternResponseDto -> - homeRecommendInternResponseDto.toHomeRecommendInternList() - } + ).result.toHomeRecommendInternList() } override suspend fun getFilteringInfo(): Result = diff --git a/data/src/main/java/com/terning/data/service/HomeService.kt b/data/src/main/java/com/terning/data/service/HomeService.kt index 16265cd36..c87dc2dce 100644 --- a/data/src/main/java/com/terning/data/service/HomeService.kt +++ b/data/src/main/java/com/terning/data/service/HomeService.kt @@ -5,22 +5,22 @@ import com.terning.data.dto.NonDataBaseResponse import com.terning.data.dto.request.ChangeFilterRequestDto import com.terning.data.dto.response.HomeFilteringInfoResponseDto import com.terning.data.dto.response.HomeRecommendInternResponseDto -import com.terning.data.dto.response.HomeTodayInternResponseDto +import com.terning.data.dto.response.HomeUpcomingInternResponseDto import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.PUT import retrofit2.http.Query interface HomeService { - @GET("api/v1/home/today") - suspend fun getHomeTodayIntern(): BaseResponse> + @GET("api/v1/home/upcoming") + suspend fun getHomeUpcomingIntern(): BaseResponse> @GET("api/v1/home") suspend fun getRecommendIntern( @Query("sortBy") sortBy: String, @Query("startYear") startYear: Int, @Query("startMonth") startMonth: Int, - ): BaseResponse> + ): BaseResponse @GET("api/v1/filters") suspend fun getFilteringInfo(): BaseResponse diff --git a/domain/src/main/java/com/terning/domain/entity/home/HomeRecommendIntern.kt b/domain/src/main/java/com/terning/domain/entity/home/HomeRecommendIntern.kt index e8e4150d9..60e4fc2df 100644 --- a/domain/src/main/java/com/terning/domain/entity/home/HomeRecommendIntern.kt +++ b/domain/src/main/java/com/terning/domain/entity/home/HomeRecommendIntern.kt @@ -1,13 +1,18 @@ package com.terning.domain.entity.home data class HomeRecommendIntern( - val scrapId: Long?, - val internshipAnnouncementId: Long, - val title: String, - val dDay: String, - val deadline: String, - val workingPeriod: String, - val startYearMonth: String, - val companyImage: String, - val isScrapped: Boolean, -) + val totalCount: Int, + val homeRecommendInternDetail: List +) { + data class HomeRecommendInternDetail( + val internshipAnnouncementId: Long, + val companyImage: String, + val dDay: String, + val title: String, + val workingPeriod: String, + val isScrapped: Boolean, + val color: String?, + val deadline: String, + val startYearMonth: String, + ) +} diff --git a/domain/src/main/java/com/terning/domain/entity/home/HomeTodayIntern.kt b/domain/src/main/java/com/terning/domain/entity/home/HomeUpcomingIntern.kt similarity index 81% rename from domain/src/main/java/com/terning/domain/entity/home/HomeTodayIntern.kt rename to domain/src/main/java/com/terning/domain/entity/home/HomeUpcomingIntern.kt index 742773035..806849c34 100644 --- a/domain/src/main/java/com/terning/domain/entity/home/HomeTodayIntern.kt +++ b/domain/src/main/java/com/terning/domain/entity/home/HomeUpcomingIntern.kt @@ -1,13 +1,13 @@ package com.terning.domain.entity.home -data class HomeTodayIntern( - val scrapId: Long, +data class HomeUpcomingIntern( val internshipAnnouncementId: Long, val companyImage: String, val title: String, val dDay: String, val deadline: String, val workingPeriod: String, + val isScrapped: Boolean, val color: String, val startYearMonth: String, ) diff --git a/domain/src/main/java/com/terning/domain/repository/HomeRepository.kt b/domain/src/main/java/com/terning/domain/repository/HomeRepository.kt index c21daa27a..e78187054 100644 --- a/domain/src/main/java/com/terning/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/terning/domain/repository/HomeRepository.kt @@ -2,17 +2,17 @@ package com.terning.domain.repository import com.terning.domain.entity.home.HomeFilteringInfo import com.terning.domain.entity.home.HomeRecommendIntern -import com.terning.domain.entity.home.HomeTodayIntern +import com.terning.domain.entity.home.HomeUpcomingIntern import com.terning.domain.entity.request.ChangeFilteringRequestModel interface HomeRepository { - suspend fun getHomeTodayInternList(): Result> + suspend fun getHomeUpcomingInternList(): Result> suspend fun getRecommendIntern( sortBy: String, startYear: Int, startMonth: Int - ): Result> + ): Result suspend fun getFilteringInfo(): Result diff --git a/feature/src/main/java/com/terning/feature/home/changefilter/ChangeFilterRoute.kt b/feature/src/main/java/com/terning/feature/home/changefilter/ChangeFilterRoute.kt deleted file mode 100644 index dfc3a938a..000000000 --- a/feature/src/main/java/com/terning/feature/home/changefilter/ChangeFilterRoute.kt +++ /dev/null @@ -1,218 +0,0 @@ -package com.terning.feature.home.changefilter - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.statusBarsPadding -import androidx.compose.material3.Scaffold -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.shadow -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.compose.LocalLifecycleOwner -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.lifecycle.flowWithLifecycle -import androidx.navigation.NavController -import com.terning.core.designsystem.component.button.RectangleButton -import com.terning.core.designsystem.component.datepicker.DatePickerUI -import com.terning.core.designsystem.component.topappbar.BackButtonTopAppBar -import com.terning.core.designsystem.theme.TerningTheme -import com.terning.core.extension.toast -import com.terning.core.state.UiState -import com.terning.domain.entity.home.HomeFilteringInfo -import com.terning.domain.entity.request.ChangeFilteringRequestModel -import com.terning.feature.R -import com.terning.feature.home.changefilter.component.ChangeFilteringRadioGroup -import com.terning.feature.home.changefilter.component.FilteringMainTitleText -import com.terning.feature.home.changefilter.component.FilteringSubTitleText -import com.terning.feature.home.changefilter.navigation.navigateChangeFilter -import com.terning.feature.home.home.HomeSideEffect -import com.terning.feature.home.home.HomeViewModel - -const val MIN_INDEX = 0 -const val MAX_WORKING_INDEX = 2 -const val MAX_GRADE_INDEX = 3 - -@Composable -fun ChangeFilterRoute( - navController: NavController, - viewModel: HomeViewModel = hiltViewModel(), -) { - val lifecycleOwner = LocalLifecycleOwner.current - val context = LocalContext.current - - val homeState by viewModel.homeState.collectAsStateWithLifecycle() - - when (homeState.homeFilteringInfoState) { - is UiState.Success -> ChangeFilterScreen( - filterData = (homeState.homeFilteringInfoState as UiState.Success).data, - navigateToHome = { navController.popBackStack() }, - viewModel, - ) - - else -> {} - } - - LaunchedEffect(viewModel.homeSideEffect, lifecycleOwner) { - viewModel.homeSideEffect.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle) - .collect { sideEffect -> - when (sideEffect) { - is HomeSideEffect.ShowToast -> context.toast(sideEffect.message) - is HomeSideEffect.NavigateToChangeFilter -> navController.navigateChangeFilter() - is HomeSideEffect.NavigateToHome -> navController.navigateUp() - } - } - } -} - -@Composable -fun ChangeFilterScreen( - filterData: HomeFilteringInfo, - navigateToHome: () -> Unit, - viewModel: HomeViewModel, -) { - var currentGrade by remember { mutableIntStateOf(filterData.grade ?: -1) } - var currentWorkingPeriod by remember { mutableIntStateOf(filterData.workingPeriod ?: -1) } - var currentStartYear by remember { - mutableIntStateOf( - filterData.startYear ?: viewModel.currentYear - ) - } - var currentStartMonth by remember { - mutableIntStateOf( - filterData.startMonth ?: viewModel.currentMonth - ) - } - - - Scaffold( - topBar = { - BackButtonTopAppBar( - title = stringResource(id = R.string.change_filter_top_bar_title), - onBackButtonClick = navigateToHome, - modifier = Modifier - .shadow(elevation = 2.dp) - ) - }, - modifier = Modifier - .statusBarsPadding() - .navigationBarsPadding() - ) { paddingValues -> - Column( - modifier = Modifier - .padding( - top = paddingValues.calculateTopPadding(), - ) - ) { - ShowTitle( - mainTitle = stringResource(id = R.string.change_filter_grade_main), - subTitle = stringResource(id = R.string.filtering_status1_sub), - modifier = Modifier.padding( - top = 31.dp, - start = 24.dp, - end = 24.dp - ) - ) - ChangeFilteringRadioGroup( - initOption = filterData.grade ?: -1, - optionList = listOf( - R.string.filtering_status1_button1, - R.string.filtering_status1_button2, - R.string.filtering_status1_button3, - R.string.filtering_status1_button4, - ), - onButtonClick = { index -> - currentGrade = index - } - ) - - ShowTitle( - mainTitle = stringResource(id = R.string.filtering_status2_title), - subTitle = stringResource(id = R.string.filtering_status2_sub), - modifier = Modifier.padding( - top = 39.dp, - start = 24.dp, - end = 24.dp - ) - ) - ChangeFilteringRadioGroup( - initOption = filterData.workingPeriod ?: -1, - optionList = listOf( - R.string.filtering_status2_button1, - R.string.filtering_status2_button2, - R.string.filtering_status2_button3, - ), - onButtonClick = { index -> - currentWorkingPeriod = index - } - ) - - ShowTitle( - mainTitle = stringResource(id = R.string.filtering_status3_title), - subTitle = stringResource(id = R.string.filtering_status3_sub), - modifier = Modifier.padding( - top = 39.dp, - start = 24.dp, - end = 24.dp - ) - ) - - Spacer(modifier = Modifier.weight(1f)) - DatePickerUI( - chosenYear = filterData.startYear ?: currentStartYear, - chosenMonth = filterData.startMonth?.minus(1) ?: currentStartMonth, - onYearChosen = { currentStartYear = it }, - onMonthChosen = { currentStartMonth = it } - ) - Spacer(modifier = Modifier.weight(1f)) - - RectangleButton( - style = TerningTheme.typography.button0, - paddingVertical = 19.dp, - text = R.string.change_filter_save, - onButtonClick = { - viewModel.putFilteringInfo( - ChangeFilteringRequestModel( - grade = currentGrade, - workingPeriod = currentWorkingPeriod, - startYear = currentStartYear, - startMonth = currentStartMonth, - ) - ) - }, - isEnabled = currentGrade in MIN_INDEX..MAX_GRADE_INDEX && currentWorkingPeriod in MIN_INDEX..MAX_WORKING_INDEX - ) - } - } -} - -@Composable -private fun ShowTitle( - mainTitle: String, - subTitle: String, - modifier: Modifier = Modifier, -) { - FilteringMainTitleText( - text = mainTitle, - modifier = modifier.padding() - ) - FilteringSubTitleText( - text = subTitle, - modifier = Modifier - .padding( - top = 3.dp, - bottom = 13.dp, - start = 24.dp, - end = 24.dp - ) - ) -} \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/changefilter/component/ChangeFilteringRadioGroup.kt b/feature/src/main/java/com/terning/feature/home/changefilter/component/ChangeFilteringRadioGroup.kt deleted file mode 100644 index 97f0c3097..000000000 --- a/feature/src/main/java/com/terning/feature/home/changefilter/component/ChangeFilteringRadioGroup.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.terning.feature.home.changefilter.component - -import androidx.compose.foundation.layout.Arrangement -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.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.Modifier -import androidx.compose.ui.unit.dp -import com.terning.core.designsystem.component.button.ChangeFilterButton - -@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(12.dp), - modifier = modifier - .fillMaxWidth() - .wrapContentHeight() - .padding(horizontal = 24.dp) - - ) { - 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/src/main/java/com/terning/feature/home/changefilter/component/FilteringMainTitleText.kt b/feature/src/main/java/com/terning/feature/home/changefilter/component/FilteringMainTitleText.kt deleted file mode 100644 index 1bc543e55..000000000 --- a/feature/src/main/java/com/terning/feature/home/changefilter/component/FilteringMainTitleText.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.terning.feature.home.changefilter.component - -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import com.terning.core.designsystem.theme.Black -import com.terning.core.designsystem.theme.TerningTheme - -@Composable -fun FilteringMainTitleText( - text: String, - modifier: Modifier = Modifier, -) { - Text( - text = text, - style = TerningTheme.typography.title3, - color = Black, - modifier = modifier, - ) -} \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/changefilter/component/FilteringSubTitleText.kt b/feature/src/main/java/com/terning/feature/home/changefilter/component/FilteringSubTitleText.kt deleted file mode 100644 index 1a26d42f4..000000000 --- a/feature/src/main/java/com/terning/feature/home/changefilter/component/FilteringSubTitleText.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.terning.feature.home.changefilter.component - -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import com.terning.core.designsystem.theme.Grey300 -import com.terning.core.designsystem.theme.TerningTheme - -@Composable -fun FilteringSubTitleText( - text: String, - modifier: Modifier = Modifier, -) { - Text( - text = text, - style = TerningTheme.typography.body5, - color = Grey300, - modifier = modifier, - ) -} \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/changefilter/navigation/ChangeFilterNavigation.kt b/feature/src/main/java/com/terning/feature/home/changefilter/navigation/ChangeFilterNavigation.kt deleted file mode 100644 index dbc6ce24a..000000000 --- a/feature/src/main/java/com/terning/feature/home/changefilter/navigation/ChangeFilterNavigation.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.terning.feature.home.changefilter.navigation - -import androidx.compose.animation.EnterTransition -import androidx.compose.animation.ExitTransition -import androidx.navigation.NavController -import androidx.navigation.NavGraphBuilder -import androidx.navigation.NavHostController -import androidx.navigation.NavOptions -import androidx.navigation.compose.composable -import com.terning.core.navigation.Route -import com.terning.feature.home.changefilter.ChangeFilterRoute -import kotlinx.serialization.Serializable - -fun NavController.navigateChangeFilter(navOptions: NavOptions? = null) { - navigate( - route = ChangeFilter, - navOptions = navOptions - ) -} - -fun NavGraphBuilder.changeFilterNavGraph( - navHostController: NavHostController -) { - composable( - exitTransition = { - ExitTransition.None - }, - popEnterTransition = { - EnterTransition.None - }, - enterTransition = { - EnterTransition.None - }, - popExitTransition = { - ExitTransition.None - } - ) { - ChangeFilterRoute( - navController = navHostController - ) - } -} - -@Serializable -data object ChangeFilter : Route \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/home/HomeRoute.kt b/feature/src/main/java/com/terning/feature/home/home/HomeRoute.kt index 2e9793e17..5cc35bf73 100644 --- a/feature/src/main/java/com/terning/feature/home/home/HomeRoute.kt +++ b/feature/src/main/java/com/terning/feature/home/home/HomeRoute.kt @@ -6,12 +6,9 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues 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.padding import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -35,40 +32,36 @@ import androidx.navigation.NavHostController import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.terning.core.designsystem.component.bottomsheet.SortingBottomSheet import com.terning.core.designsystem.component.button.SortingButton -import com.terning.core.designsystem.component.dialog.ScrapCancelDialogContent -import com.terning.core.designsystem.component.dialog.TerningBasicDialog import com.terning.core.designsystem.component.image.TerningImage import com.terning.core.designsystem.component.item.InternItemWithShadow import com.terning.core.designsystem.theme.Black -import com.terning.core.designsystem.theme.CalBlue1 -import com.terning.core.designsystem.theme.CalBlue2 -import com.terning.core.designsystem.theme.CalGreen1 -import com.terning.core.designsystem.theme.CalGreen2 -import com.terning.core.designsystem.theme.CalOrange1 -import com.terning.core.designsystem.theme.CalOrange2 -import com.terning.core.designsystem.theme.CalPink -import com.terning.core.designsystem.theme.CalPurple import com.terning.core.designsystem.theme.CalRed -import com.terning.core.designsystem.theme.CalYellow -import com.terning.core.designsystem.theme.Grey150 +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.extension.currentMonth +import com.terning.core.extension.currentYear import com.terning.core.extension.noRippleClickable import com.terning.core.extension.toast import com.terning.core.state.UiState +import com.terning.core.type.Grade +import com.terning.core.type.WorkingPeriod import com.terning.domain.entity.home.HomeFilteringInfo import com.terning.domain.entity.home.HomeRecommendIntern -import com.terning.domain.entity.home.HomeTodayIntern +import com.terning.domain.entity.home.HomeUpcomingIntern import com.terning.feature.R -import com.terning.feature.home.changefilter.navigation.navigateChangeFilter -import com.terning.feature.home.home.component.HomeFilteringEmptyIntern +import com.terning.feature.calendar.calendar.navigation.navigateCalendar +import com.terning.feature.dialog.cancel.ScrapCancelDialog +import com.terning.feature.dialog.detail.ScrapDialog +import com.terning.feature.home.home.component.HomeFilteringBottomSheet import com.terning.feature.home.home.component.HomeFilteringScreen import com.terning.feature.home.home.component.HomeRecommendEmptyIntern -import com.terning.feature.home.home.component.HomeRecommendInternDialog -import com.terning.feature.home.home.component.HomeTodayEmptyWithImg -import com.terning.feature.home.home.component.HomeTodayIntern -import com.terning.feature.home.home.model.HomeDialogState +import com.terning.feature.home.home.component.HomeUpcomingEmptyFilter +import com.terning.feature.home.home.component.HomeUpcomingEmptyIntern +import com.terning.feature.home.home.component.HomeUpcomingInternScreen import com.terning.feature.intern.navigation.navigateIntern +import java.util.Calendar const val NAME_START_LENGTH = 7 const val NAME_END_LENGTH = 12 @@ -92,8 +85,6 @@ fun HomeRoute( val lifecycleOwner = LocalLifecycleOwner.current val context = LocalContext.current - val homeDialogState by viewModel.homeDialogState.collectAsStateWithLifecycle() - LaunchedEffect(key1 = true) { viewModel.getFilteringInfo() } @@ -103,7 +94,6 @@ fun HomeRoute( .collect { sideEffect -> when (sideEffect) { is HomeSideEffect.ShowToast -> context.toast(sideEffect.message) - is HomeSideEffect.NavigateToChangeFilter -> navController.navigateChangeFilter() is HomeSideEffect.NavigateToHome -> navController.navigateUp() } } @@ -111,9 +101,8 @@ fun HomeRoute( HomeScreen( paddingValues = paddingValues, - homeDialogState = homeDialogState, - onChangeFilterClick = { navController.navigateChangeFilter() }, navigateToIntern = { navController.navigateIntern(announcementId = it) }, + navigateToCalendar = { navController.navigateCalendar() }, viewModel = viewModel, ) } @@ -122,9 +111,8 @@ fun HomeRoute( @Composable fun HomeScreen( paddingValues: PaddingValues, - homeDialogState: HomeDialogState, - onChangeFilterClick: () -> Unit, navigateToIntern: (Long) -> Unit, + navigateToCalendar: () -> Unit, viewModel: HomeViewModel, ) { val homeState by viewModel.homeState.collectAsStateWithLifecycle() @@ -140,18 +128,23 @@ fun HomeScreen( } val homeRecommendInternList = when (homeState.homeRecommendInternState) { - is UiState.Success -> (homeState.homeRecommendInternState as UiState.Success>).data + is UiState.Success -> (homeState.homeRecommendInternState as UiState.Success).data.homeRecommendInternDetail else -> listOf() } + val homeRecommendInternTotal = when (homeState.homeRecommendInternState) { + is UiState.Success -> (homeState.homeRecommendInternState as UiState.Success).data.totalCount + else -> 0 + } + val currentSortBy: MutableState = remember { mutableIntStateOf(0) } - var sheetState by remember { mutableStateOf(false) } - var scrapId by remember { mutableIntStateOf(-1) } + var sortingSheetState by remember { mutableStateOf(false) } + var changeFilteringSheetState by remember { mutableStateOf(false) } - if (sheetState) { + if (sortingSheetState) { SortingBottomSheet( onDismiss = { - sheetState = false + sortingSheetState = false viewModel.getRecommendInternsData( currentSortBy.value, homeFilteringInfo.startYear, @@ -163,6 +156,44 @@ fun HomeScreen( ) } + if (changeFilteringSheetState) { + HomeFilteringBottomSheet( + defaultGrade = homeFilteringInfo.grade?.let { Grade.entries[it] }, + defaultWorkingPeriod = homeFilteringInfo.workingPeriod?.let { + WorkingPeriod.entries[it] + }, + defaultStartYear = homeFilteringInfo.startYear, + defaultStartMonth = homeFilteringInfo.startMonth, + onDismiss = { changeFilteringSheetState = false }, + onChangeButtonClick = { grade, workingPeriod, year, month -> + viewModel.putFilteringInfo(grade, workingPeriod, year, month) + changeFilteringSheetState = false + } + ) + } + + LaunchedEffect(changeFilteringSheetState) { + if (!changeFilteringSheetState) { + viewModel.getFilteringInfo() + } + } + + LaunchedEffect( + homeState.homeRecommendDialogVisibility, + homeState.homeUpcomingDialogVisibility + ) { + with(homeState) { + if (!homeRecommendDialogVisibility && !homeUpcomingDialogVisibility) { + viewModel.getRecommendInternsData( + sortBy = sortBy.ordinal, + startYear = homeFilteringInfo.startYear ?: Calendar.getInstance().currentYear, + startMonth = homeFilteringInfo.startMonth + ?: Calendar.getInstance().currentMonth, + ) + } + } + } + Column( horizontalAlignment = Alignment.Start, modifier = Modifier @@ -190,10 +221,11 @@ fun HomeScreen( .padding(bottom = 16.dp) ) { ShowMainTitleWithName(homeUserName) - ShowTodayIntern( - homeTodayInternState = homeState.homeTodayInternState, - homeDialogState = homeDialogState, - navigateToIntern = { navigateToIntern(it) } + ShowUpcomingIntern( + homeUpcomingInternState = homeState.homeUpcomingInternState, + homeState = homeState, + navigateToIntern = { navigateToIntern(it) }, + navigateToCalendar = navigateToCalendar, ) } } @@ -203,27 +235,45 @@ fun HomeScreen( .background(White) ) { ShowRecommendTitle() - ShowInternFilter(homeFilteringInfo = homeFilteringInfo, onChangeFilterClick) - - HorizontalDivider( - thickness = 4.dp, - color = Grey150, + ShowInternFilter( + homeFilteringInfo = homeFilteringInfo, + onChangeFilterClick = { changeFilteringSheetState = true }, ) Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, modifier = Modifier - .fillMaxWidth(), - horizontalArrangement = Arrangement.End, + .fillMaxWidth() + .padding(start = 24.dp, end = 18.dp), ) { - SortingButton( - sortBy = currentSortBy.value, - onCLick = { sheetState = true }, - modifier = Modifier - .padding(vertical = 4.dp) - ) - Spacer( - modifier = Modifier.padding(9.dp) - ) + Row { + Text( + text = stringResource(id = R.string.home_recommend_total), + style = TerningTheme.typography.detail1, + color = Grey400, + modifier = Modifier + .padding(end = 3.dp), + ) + Text( + text = homeRecommendInternTotal.toString(), + style = TerningTheme.typography.button3, + color = TerningMain, + ) + Text( + text = stringResource(id = R.string.home_recommend_count), + style = TerningTheme.typography.detail1, + color = Grey400, + ) + } + Row { + SortingButton( + sortBy = currentSortBy.value, + onCLick = { sortingSheetState = true }, + modifier = Modifier + .padding(vertical = 4.dp) + ) + } } } } @@ -234,111 +284,75 @@ fun HomeScreen( navigateToIntern = navigateToIntern, intern = homeRecommendInternList[index], onScrapButtonClicked = { - viewModel.updateScrapDialogVisible(true) - viewModel.updateIsToday(false) - scrapId = index - } - ) - } - } - } - if (homeState.homeFilteringInfoState is UiState.Success && homeFilteringInfo.grade == null) { - HomeFilteringEmptyIntern( - modifier = Modifier - .padding(horizontal = 24.dp) - .fillMaxSize() - ) - } else if (homeRecommendInternList.isEmpty()) { - HomeRecommendEmptyIntern() - } - } - - if (homeDialogState.isScrapDialogVisible && !homeDialogState.isToday) { - TerningBasicDialog( - onDismissRequest = { - viewModel.updateScrapDialogVisible(false) - viewModel.updatePaletteOpen(false) - }, - content = { - if (homeRecommendInternList[scrapId].scrapId != null) { - ScrapCancelDialogContent( - onClickScrapCancel = { - viewModel.updateScrapDialogVisible(false) - viewModel.deleteScrap( - homeRecommendInternList[scrapId].scrapId ?: -1, - ) - if (homeDialogState.isScrappedState) { - viewModel.getRecommendInternsData( - currentSortBy.value, - homeFilteringInfo.startYear, - homeFilteringInfo.startMonth, + viewModel.updateRecommendDialogVisibility(true) + with(homeRecommendInternList[index]) { + viewModel.updateHomeInternModel( + internshipAnnouncementId = internshipAnnouncementId, + companyImage = companyImage, + title = title, + dDay = dDay, + deadline = deadline, + workingPeriod = workingPeriod, + isScrapped = isScrapped, + color = color, + startYearMonth = startYearMonth, ) - viewModel.updateScrapped(false) } } ) - } else { - val colorList = listOf( - CalRed, - CalOrange1, - CalOrange2, - CalYellow, - CalGreen1, - CalGreen2, - CalBlue1, - CalBlue2, - CalPurple, - CalPink, - ) - - val selectedColorIndex = - colorList.indexOf(homeDialogState.selectedColor).takeIf { it >= 0 } ?: 0 - with(homeRecommendInternList[scrapId]) { - HomeRecommendInternDialog( - internInfoList = listOf( - stringResource(id = R.string.intern_info_d_day) to deadline, - stringResource(id = R.string.intern_info_working) to workingPeriod, - stringResource(id = R.string.intern_info_start_date) to startYearMonth, - ), - clickAction = { - if (homeDialogState.isPaletteOpen) { - viewModel.updatePaletteOpen(false) - viewModel.updateColorChange(false) - viewModel.updateScrapDialogVisible(false) + if (homeState.homeRecommendDialogVisibility) { + with(homeState.homeInternModel) { + if (this != null) { + if (isScrapped) { + ScrapCancelDialog( + internshipAnnouncementId = internshipAnnouncementId, + onDismissRequest = { + viewModel.updateRecommendDialogVisibility(false) + viewModel.getHomeUpcomingInternList() + } + ) } else { - if (homeDialogState.isColorChange) { - viewModel.updateColorChange(false) - } - viewModel.updateScrapDialogVisible(false) - } - viewModel.postScrap( - homeRecommendInternList[scrapId].internshipAnnouncementId, - selectedColorIndex, - ) - viewModel.updateScrapDialogVisible(false) - if (homeDialogState.isScrappedState) { - viewModel.getRecommendInternsData( - currentSortBy.value, - homeFilteringInfo.startYear, - homeFilteringInfo.startMonth, + ScrapDialog( + title = title, + scrapColor = CalRed, + deadline = deadline, + startYearMonth = startYearMonth, + workingPeriod = workingPeriod, + internshipAnnouncementId = internshipAnnouncementId, + companyImage = companyImage, + isScrapped = isScrapped, + onDismissRequest = { + viewModel.updateRecommendDialogVisibility( + false + ) + viewModel.getHomeUpcomingInternList() + }, + onClickChangeColor = { /*TODO*/ }, + onClickNavigateButton = navigateToIntern ) - viewModel.updateScrapped(false) } - }, - homeRecommendIntern = this, - ) + } + } } } + } else { + 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 + ) + } } - ) + } } } @Composable private fun RecommendInternItem( - intern: HomeRecommendIntern, + intern: HomeRecommendIntern.HomeRecommendInternDetail, navigateToIntern: (Long) -> Unit, onScrapButtonClicked: (Long) -> Unit, ) { @@ -363,7 +377,7 @@ private fun RecommendInternItem( private fun ShowMainTitleWithName(userName: String) { Text( text = stringResource( - id = R.string.home_today_title, + id = R.string.home_upcoming_title, if (userName.length in NAME_START_LENGTH..NAME_END_LENGTH) "\n" + userName else userName ), @@ -376,40 +390,33 @@ private fun ShowMainTitleWithName(userName: String) { } @Composable -private fun ShowTodayIntern( - homeTodayInternState: UiState>, - homeDialogState: HomeDialogState, +private fun ShowUpcomingIntern( + homeUpcomingInternState: UiState>, + homeState: HomeState, navigateToIntern: (Long) -> Unit, + navigateToCalendar: () -> Unit, ) { - when (homeTodayInternState) { + when (homeUpcomingInternState) { is UiState.Success -> { - if (homeTodayInternState.data.isEmpty()) { - HomeTodayEmptyWithImg() + if (homeUpcomingInternState.data.isEmpty()) { + HomeUpcomingEmptyIntern(navigateToCalendar = navigateToCalendar) } else { - HomeTodayIntern( - internList = homeTodayInternState.data, - homeDialogState = homeDialogState, - navigateToIntern = { navigateToIntern(it) }, + HomeUpcomingInternScreen( + internList = homeUpcomingInternState.data, + homeState = homeState, + navigateToIntern = navigateToIntern ) } } - is UiState.Loading -> HomeTodayEmptyWithImg() + is UiState.Loading -> HomeUpcomingEmptyFilter() + is UiState.Empty -> HomeUpcomingEmptyFilter() else -> {} } } @Composable private fun ShowRecommendTitle() { - Text( - text = stringResource(id = R.string.home_recommend_sub_title), - style = TerningTheme.typography.detail2, - color = Black, - modifier = Modifier - .padding(top = 9.dp) - .padding(horizontal = 24.dp), - ) - Text( text = stringResource(id = R.string.home_recommend_main_title), style = TerningTheme.typography.title1, @@ -425,29 +432,8 @@ private fun ShowInternFilter( homeFilteringInfo: HomeFilteringInfo, onChangeFilterClick: () -> Unit, ) { - if (homeFilteringInfo.grade == null) { - HomeFilteringScreen( - grade = stringResource(id = R.string.home_recommend_no_filtering_hyphen), - period = stringResource(id = R.string.home_recommend_no_filtering_hyphen), - startYear = stringResource(id = R.string.home_recommend_no_filtering_hyphen), - onChangeFilterClick = onChangeFilterClick, - ) - } else { - with(homeFilteringInfo) { - HomeFilteringScreen( - grade = (grade?.plus(1)).toString() + stringResource(id = R.string.home_recommend_filtering_grade), - period = stringResource( - id = when (workingPeriod) { - 0 -> R.string.filtering_status2_button1 - 1 -> R.string.filtering_status2_button2 - 2 -> R.string.filtering_status2_button3 - else -> R.string.home_recommend_no_filtering_hyphen - } - ), - startYear = startYear.toString() + stringResource(id = R.string.home_recommend_filtering_startYear) - + " " + startMonth.toString() + stringResource(id = R.string.home_recommend_filtering_startMonth), - onChangeFilterClick = onChangeFilterClick, - ) - } - } + HomeFilteringScreen( + homeFilteringInfo = homeFilteringInfo, + onChangeFilterClick = onChangeFilterClick, + ) } diff --git a/feature/src/main/java/com/terning/feature/home/home/HomeSideEffect.kt b/feature/src/main/java/com/terning/feature/home/home/HomeSideEffect.kt index de575f6ff..ec74db512 100644 --- a/feature/src/main/java/com/terning/feature/home/home/HomeSideEffect.kt +++ b/feature/src/main/java/com/terning/feature/home/home/HomeSideEffect.kt @@ -4,6 +4,5 @@ import androidx.annotation.StringRes sealed class HomeSideEffect { data class ShowToast(@StringRes val message: Int) : HomeSideEffect() - data object NavigateToChangeFilter : HomeSideEffect() data object NavigateToHome : HomeSideEffect() } \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/home/HomeState.kt b/feature/src/main/java/com/terning/feature/home/home/HomeState.kt index fdee536c3..4b7cde0fb 100644 --- a/feature/src/main/java/com/terning/feature/home/home/HomeState.kt +++ b/feature/src/main/java/com/terning/feature/home/home/HomeState.kt @@ -1,15 +1,18 @@ package com.terning.feature.home.home import com.terning.core.state.UiState +import com.terning.core.type.SortBy import com.terning.domain.entity.home.HomeFilteringInfo import com.terning.domain.entity.home.HomeRecommendIntern -import com.terning.domain.entity.home.HomeTodayIntern -import com.terning.feature.home.home.model.SortBy +import com.terning.domain.entity.home.HomeUpcomingIntern data class HomeState( val sortBy: SortBy = SortBy.EARLIEST, val homeUserNameState: UiState = UiState.Loading, val homeFilteringInfoState: UiState = UiState.Loading, - val homeTodayInternState: UiState> = UiState.Loading, - val homeRecommendInternState: UiState> = UiState.Loading, + val homeUpcomingInternState: UiState> = UiState.Empty, + val homeRecommendInternState: UiState = UiState.Loading, + val homeUpcomingDialogVisibility: Boolean = false, + val homeRecommendDialogVisibility: Boolean = false, + val homeInternModel: HomeUpcomingIntern? = null, ) diff --git a/feature/src/main/java/com/terning/feature/home/home/HomeViewModel.kt b/feature/src/main/java/com/terning/feature/home/home/HomeViewModel.kt index 3269ce21f..b12d647b6 100644 --- a/feature/src/main/java/com/terning/feature/home/home/HomeViewModel.kt +++ b/feature/src/main/java/com/terning/feature/home/home/HomeViewModel.kt @@ -1,18 +1,16 @@ package com.terning.feature.home.home -import androidx.compose.ui.graphics.Color import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.terning.core.designsystem.theme.CalRed +import com.terning.core.extension.currentMonth +import com.terning.core.extension.currentYear import com.terning.core.state.UiState -import com.terning.domain.entity.calendar.CalendarScrapRequest +import com.terning.core.type.SortBy +import com.terning.domain.entity.home.HomeUpcomingIntern import com.terning.domain.entity.request.ChangeFilteringRequestModel import com.terning.domain.repository.HomeRepository import com.terning.domain.repository.MyPageRepository -import com.terning.domain.repository.ScrapRepository import com.terning.feature.R -import com.terning.feature.home.home.model.HomeDialogState -import com.terning.feature.home.home.model.SortBy import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -27,21 +25,13 @@ import javax.inject.Inject class HomeViewModel @Inject constructor( private val homeRepository: HomeRepository, private val myPageRepository: MyPageRepository, - private val scrapRepository: ScrapRepository, ) : ViewModel() { - val currentYear = Calendar.getInstance().get(Calendar.YEAR) - val currentMonth = Calendar.getInstance().get(Calendar.MONTH) - private val _homeState: MutableStateFlow = MutableStateFlow(HomeState()) val homeState get() = _homeState.asStateFlow() private val _homeSideEffect = MutableSharedFlow() val homeSideEffect get() = _homeSideEffect.asSharedFlow() - private val _homeDialogState: MutableStateFlow = - MutableStateFlow(HomeDialogState()) - val homeDialogState get() = _homeDialogState.asStateFlow() - init { getProfile() getFilteringInfo() @@ -50,32 +40,31 @@ class HomeViewModel @Inject constructor( fun getRecommendInternsData(sortBy: Int, startYear: Int?, startMonth: Int?) { viewModelScope.launch { homeRepository.getRecommendIntern( - SortBy.entries[sortBy].sortBy, - startYear ?: currentYear, - startMonth ?: currentMonth, - ) - .onSuccess { internList -> - _homeState.value = _homeState.value.copy( - homeRecommendInternState = UiState.Success(internList) - ) - }.onFailure { exception: Throwable -> - _homeState.value = _homeState.value.copy( - homeRecommendInternState = UiState.Failure(exception.toString()) - ) - _homeSideEffect.emit(HomeSideEffect.ShowToast(R.string.server_failure)) - } + sortBy = SortBy.entries[sortBy].type, + startYear ?: Calendar.getInstance().currentYear, + startMonth ?: Calendar.getInstance().currentMonth, + ).onSuccess { internList -> + _homeState.value = _homeState.value.copy( + homeRecommendInternState = UiState.Success(internList) + ) + }.onFailure { exception: Throwable -> + _homeState.value = _homeState.value.copy( + homeRecommendInternState = UiState.Failure(exception.toString()) + ) + _homeSideEffect.emit(HomeSideEffect.ShowToast(R.string.server_failure)) + } } } - private fun getHomeTodayInternList() { + fun getHomeUpcomingInternList() { viewModelScope.launch { - homeRepository.getHomeTodayInternList().onSuccess { internList -> + homeRepository.getHomeUpcomingInternList().onSuccess { internList -> _homeState.value = _homeState.value.copy( - homeTodayInternState = UiState.Success(internList) + homeUpcomingInternState = UiState.Success(internList) ) }.onFailure { exception: Throwable -> _homeState.value = _homeState.value.copy( - homeTodayInternState = UiState.Failure(exception.toString()) + homeUpcomingInternState = UiState.Failure(exception.toString()) ) _homeSideEffect.emit(HomeSideEffect.ShowToast(R.string.server_failure)) } @@ -88,12 +77,14 @@ class HomeViewModel @Inject constructor( _homeState.value = _homeState.value.copy( homeFilteringInfoState = UiState.Success(filteringInfo) ) - getHomeTodayInternList() - getRecommendInternsData( - sortBy = _homeState.value.sortBy.ordinal, - startYear = filteringInfo.startYear, - startMonth = filteringInfo.startMonth, - ) + if (filteringInfo.grade != null) { + getHomeUpcomingInternList() + getRecommendInternsData( + sortBy = _homeState.value.sortBy.ordinal, + startYear = filteringInfo.startYear, + startMonth = filteringInfo.startMonth, + ) + } }.onFailure { exception: Throwable -> _homeState.value = _homeState.value.copy( homeFilteringInfoState = UiState.Failure(exception.toString()) @@ -103,13 +94,11 @@ class HomeViewModel @Inject constructor( } } - fun putFilteringInfo(changeFilterRequest: ChangeFilteringRequestModel) { + fun putFilteringInfo(grade: Int, workingPeriod: Int, year: Int, month: Int) { viewModelScope.launch { homeRepository.putFilteringInfo( - changeFilterRequest - ).onSuccess { - _homeSideEffect.emit(HomeSideEffect.NavigateToHome) - } + ChangeFilteringRequestModel(grade, workingPeriod, year, month) + ) } } @@ -127,99 +116,44 @@ class HomeViewModel @Inject constructor( } } - fun postScrap( - internshipAnnouncementId: Long, - colorIndex: Int, - ) { - viewModelScope.launch { - scrapRepository.postScrap( - CalendarScrapRequest( - id = internshipAnnouncementId, - color = colorIndex, - ) - ).onSuccess { - updateScrapDialogVisible(visible = false) - updateScrapped(scrapped = true) - updateSelectColor(CalRed) - getHomeTodayInternList() - getFilteringInfo() - _homeSideEffect.emit(HomeSideEffect.ShowToast(R.string.intern_scrap_add_toast_message)) - }.onFailure { - _homeSideEffect.emit(HomeSideEffect.ShowToast(R.string.server_failure)) - } + fun updateUpcomingDialogVisibility(visibility: Boolean) { + _homeState.update { + it.copy(homeUpcomingDialogVisibility = visibility) } } - fun deleteScrap(scrapId: Long) { - viewModelScope.launch { - scrapRepository.deleteScrap( - CalendarScrapRequest(id = scrapId) - ).onSuccess { - updateScrapDialogVisible(visible = false) - updateScrapped(scrapped = true) - getHomeTodayInternList() - getFilteringInfo() - _homeSideEffect.emit(HomeSideEffect.ShowToast(R.string.intern_scrap_delete_toast_message)) - }.onFailure { - _homeSideEffect.emit(HomeSideEffect.ShowToast(R.string.server_failure)) - } + fun updateRecommendDialogVisibility(visibility: Boolean) { + _homeState.update { + it.copy(homeRecommendDialogVisibility = visibility) } } - fun patchScrap( - scrapId: Long, - colorIndex: Int, + fun updateHomeInternModel( + internshipAnnouncementId: Long, + companyImage: String, + title: String, + dDay: String, + deadline: String, + workingPeriod: String, + isScrapped: Boolean, + color: String?, + startYearMonth: String, ) { - viewModelScope.launch { - scrapRepository.patchScrap( - CalendarScrapRequest( - id = scrapId, - color = colorIndex, + _homeState.update { + it.copy( + homeInternModel = + HomeUpcomingIntern( + internshipAnnouncementId = internshipAnnouncementId, + companyImage = companyImage, + title = title, + dDay = dDay, + deadline = deadline, + workingPeriod = workingPeriod, + isScrapped = isScrapped, + color = color ?: "", + startYearMonth = startYearMonth, ) - ).onSuccess { - updateScrapDialogVisible(visible = false) - updateScrapped(scrapped = true) - updateSelectColor(CalRed) - getHomeTodayInternList() - }.onFailure { - _homeSideEffect.emit(HomeSideEffect.ShowToast(R.string.server_failure)) - } - } - } - - fun updateSelectColor(newColor: Color) { - _homeDialogState.update { - it.copy(selectedColor = newColor) - } - } - - fun updateScrapDialogVisible(visible: Boolean) { - _homeDialogState.update { - it.copy(isScrapDialogVisible = visible) - } - } - - fun updateScrapped(scrapped: Boolean) { - _homeDialogState.update { - it.copy(isScrappedState = scrapped) - } - } - - fun updatePaletteOpen(open: Boolean) { - _homeDialogState.update { - it.copy(isPaletteOpen = open) - } - } - - fun updateColorChange(change: Boolean) { - _homeDialogState.update { - it.copy(isColorChange = change) - } - } - - fun updateIsToday(change: Boolean) { - _homeDialogState.update { - it.copy(isToday = change) + ) } } } \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/home/component/HomeFilteringBottomSheet.kt b/feature/src/main/java/com/terning/feature/home/home/component/HomeFilteringBottomSheet.kt new file mode 100644 index 000000000..096c0952e --- /dev/null +++ b/feature/src/main/java/com/terning/feature/home/home/component/HomeFilteringBottomSheet.kt @@ -0,0 +1,208 @@ +package com.terning.feature.home.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.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.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.theme.Black +import com.terning.core.designsystem.theme.Grey200 +import com.terning.core.designsystem.theme.TerningTheme +import com.terning.core.extension.currentMonth +import com.terning.core.extension.currentYear +import com.terning.core.type.Grade +import com.terning.core.type.WorkingPeriod +import com.terning.feature.filtering.filteringthree.component.YearMonthPicker +import java.util.Calendar + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun HomeFilteringBottomSheet( + modifier: Modifier = Modifier, + defaultGrade: Grade?, + defaultWorkingPeriod: WorkingPeriod?, + defaultStartYear: Int?, + defaultStartMonth: Int?, + onDismiss: () -> Unit, + onChangeButtonClick: (Int, Int, 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 + ) + } + + TerningBasicBottomSheet( + content = { + Column( + modifier = modifier + .padding(horizontal = 24.dp) + .fillMaxWidth(), + ) { + Text( + text = stringResource(id = R.string.change_filter_top_bar_title), + style = TerningTheme.typography.title2, + color = Black, + modifier = Modifier + .padding(bottom = 16.dp), + ) + + HorizontalDivider( + thickness = 1.dp, + color = Grey200, + ) + + ChangeFilteringTitleText( + text = stringResource(id = R.string.change_filter_grade_title), + modifier = Modifier + .padding(top = 18.dp, bottom = 12.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] + } + ) + + ChangeFilteringTitleText( + text = stringResource(id = R.string.change_filter_period_title), + modifier = Modifier + .padding(top = 32.dp, bottom = 12.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] + } + ) + + ChangeFilteringTitleText( + text = stringResource(id = R.string.change_filter_start_work_title), + modifier = Modifier + .padding(top = 32.dp, bottom = 49.dp) + ) + + YearMonthPicker( + chosenYear = defaultStartYear ?: Calendar.getInstance().currentYear, + chosenMonth = defaultStartMonth?.minus(1) + ?: Calendar.getInstance().currentMonth.minus(1), + onYearChosen = { currentStartYear = it }, + onMonthChosen = { currentStartMonth = it } + ) + RoundButton( + style = TerningTheme.typography.button0, + paddingVertical = 19.dp, + text = R.string.change_filter_save, + cornerRadius = 10.dp, + modifier = Modifier + .padding(top = 51.dp), + onButtonClick = { + currentGrade?.let { grade -> + currentPeriod?.let { workingPeriod -> + onChangeButtonClick( + grade.ordinal, + workingPeriod.ordinal, + 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(12.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/src/main/java/com/terning/feature/home/home/component/HomeFilteringEmptyIntern.kt b/feature/src/main/java/com/terning/feature/home/home/component/HomeFilteringEmptyIntern.kt deleted file mode 100644 index b1ffeeda7..000000000 --- a/feature/src/main/java/com/terning/feature/home/home/component/HomeFilteringEmptyIntern.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.terning.feature.home.home.component - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import com.terning.core.designsystem.component.image.TerningImage -import com.terning.core.designsystem.theme.Grey500 -import com.terning.core.designsystem.theme.TerningTheme -import com.terning.feature.R - -@Composable -fun HomeFilteringEmptyIntern( - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.Center - ) { - - TerningImage( - painter = R.drawable.ic_home_empty_filtering, - modifier = Modifier - .align(Alignment.CenterHorizontally) - ) - Text( - text = stringResource(id = R.string.home_recommend_no_filtering), - modifier = Modifier - .fillMaxWidth() - .align(Alignment.CenterHorizontally), - style = TerningTheme.typography.detail2, - color = Grey500, - textAlign = TextAlign.Center, - ) - } -} \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/home/component/HomeFilteringScreen.kt b/feature/src/main/java/com/terning/feature/home/home/component/HomeFilteringScreen.kt index 8011d60cf..a3db7832b 100644 --- a/feature/src/main/java/com/terning/feature/home/home/component/HomeFilteringScreen.kt +++ b/feature/src/main/java/com/terning/feature/home/home/component/HomeFilteringScreen.kt @@ -1,114 +1,131 @@ package com.terning.feature.home.home.component -import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight 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.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon import androidx.compose.material3.Text -import androidx.compose.material3.VerticalDivider 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.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import com.terning.core.designsystem.theme.Black -import com.terning.core.designsystem.theme.Grey300 +import com.terning.core.designsystem.theme.Grey350 +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.extension.noRippleClickable +import com.terning.core.type.Grade +import com.terning.core.type.WorkingPeriod +import com.terning.domain.entity.home.HomeFilteringInfo import com.terning.feature.R @Composable fun HomeFilteringScreen( - grade: String, - period: String, - startYear: String, + homeFilteringInfo: HomeFilteringInfo, onChangeFilterClick: () -> Unit, modifier: Modifier = Modifier, ) { Row( modifier = modifier - .padding(top = 10.dp, bottom = 11.dp) - .padding(horizontal = 24.dp) + .padding(horizontal = 24.dp, vertical = 12.dp) .height(IntrinsicSize.Min) .fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, ) { Row( - modifier = modifier - .background( + modifier = Modifier + .border( + width = 1.dp, color = TerningMain, - shape = RoundedCornerShape(5.dp), + shape = RoundedCornerShape(5.dp) ) .align(Alignment.CenterVertically) - .noRippleClickable { onChangeFilterClick() }, + .noRippleClickable(onChangeFilterClick), ) { - Image( + Icon( painter = painterResource(id = R.drawable.ic_home_filtering_28), contentDescription = stringResource(id = R.string.home_recommend_filtering), modifier = modifier - .padding(horizontal = 2.dp), + .padding(start = 1.dp), + tint = TerningMain, ) Text( text = stringResource(id = R.string.home_recommend_filtering), - style = TerningTheme.typography.button4, - color = White, + style = TerningTheme.typography.button3, + color = TerningMain, textAlign = TextAlign.Center, - modifier = modifier - .padding(end = 6.dp) - .align(Alignment.CenterVertically) + modifier = Modifier + .padding(start = 5.dp, end = 10.dp) + .align(Alignment.CenterVertically), ) } - - HomeFilteringText( - text = grade, - modifier = Modifier - .padding(vertical = 7.dp) - ) - HomeFilteringDivider() - HomeFilteringText( - text = period, - modifier = Modifier - .padding(vertical = 7.dp) - ) - HomeFilteringDivider() - HomeFilteringText( - text = startYear, - modifier = Modifier - .padding(top = 7.dp, bottom = 7.dp) - ) + with(homeFilteringInfo) { + if (grade != null) { + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + HomeFilteringInfoText( + text = stringResource(id = Grade.entries[grade!!].stringResId), + modifier = Modifier + .padding(end = 6.dp), + ) + HomeFilteringInfoDivider() + HomeFilteringInfoText( + text = stringResource(WorkingPeriod.entries[workingPeriod!!].stringResId), + modifier = Modifier + .padding(horizontal = 6.dp), + ) + HomeFilteringInfoDivider() + HomeFilteringInfoText( + text = "$startYear 년 $startMonth 월", + modifier = Modifier + .padding(start = 6.dp), + ) + } + } else { + HomeFilteringInfoText( + text = stringResource(id = R.string.home_filtering_empty), + modifier = Modifier + .align(Alignment.CenterVertically), + ) + } + } } } @Composable -private fun HomeFilteringText( +private fun HomeFilteringInfoText( text: String, modifier: Modifier = Modifier ) { Text( text = text, - style = TerningTheme.typography.detail2, - color = Black, + style = TerningTheme.typography.body5, + color = Grey400, modifier = modifier, ) } @Composable -private fun HomeFilteringDivider() { - VerticalDivider( - color = Grey300, - thickness = 2.dp, +private fun HomeFilteringInfoDivider() { + Box( modifier = Modifier - .fillMaxHeight() - .padding(vertical = 4.dp), + .size(4.dp) + .clip(CircleShape) + .background(Grey350), ) } \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/home/component/HomeRecommendEmptyIntern.kt b/feature/src/main/java/com/terning/feature/home/home/component/HomeRecommendEmptyIntern.kt index fa080f323..e05dad5ed 100644 --- a/feature/src/main/java/com/terning/feature/home/home/component/HomeRecommendEmptyIntern.kt +++ b/feature/src/main/java/com/terning/feature/home/home/component/HomeRecommendEmptyIntern.kt @@ -1,5 +1,6 @@ package com.terning.feature.home.home.component +import androidx.annotation.StringRes import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -12,13 +13,16 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.terning.core.designsystem.theme.Grey400 +import com.terning.core.designsystem.theme.TerningPointTheme import com.terning.core.designsystem.theme.TerningTheme import com.terning.feature.R @Composable fun HomeRecommendEmptyIntern( + @StringRes text: Int, modifier: Modifier = Modifier, ) { Column( @@ -27,19 +31,27 @@ fun HomeRecommendEmptyIntern( verticalArrangement = Arrangement.Center, ) { Image( - painter = painterResource(id = R.drawable.ic_empty_logo), + painter = painterResource(id = R.drawable.ic_home_empty_filtering), contentDescription = stringResource(id = R.string.home_recommend_no_intern_description), modifier = modifier .align(Alignment.CenterHorizontally) ) Text( - text = stringResource(id = R.string.home_recommend_no_intern), + text = stringResource(id = text), style = TerningTheme.typography.body4, color = Grey400, textAlign = TextAlign.Center, modifier = modifier - .padding(top = 8.dp) + .padding(top = 4.dp) .align(Alignment.CenterHorizontally) ) } +} + +@Preview(showBackground = true) +@Composable +fun HomeRecommendInternPreview() { + TerningPointTheme { + HomeRecommendEmptyIntern(R.string.home_recommend_no_intern) + } } \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/home/component/HomeRecommendInternDialog.kt b/feature/src/main/java/com/terning/feature/home/home/component/HomeRecommendInternDialog.kt deleted file mode 100644 index 776cf9081..000000000 --- a/feature/src/main/java/com/terning/feature/home/home/component/HomeRecommendInternDialog.kt +++ /dev/null @@ -1,221 +0,0 @@ -package com.terning.feature.home.home.component - -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -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.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import coil.compose.AsyncImage -import coil.request.ImageRequest -import com.terning.core.R -import com.terning.core.designsystem.component.button.RoundButton -import com.terning.core.designsystem.component.item.ColorPalette -import com.terning.core.designsystem.theme.CalRed -import com.terning.core.designsystem.theme.Grey200 -import com.terning.core.designsystem.theme.Grey350 -import com.terning.core.designsystem.theme.Grey500 -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.extension.noRippleClickable -import com.terning.domain.entity.home.HomeRecommendIntern -import com.terning.feature.home.home.HomeViewModel -import com.terning.feature.intern.component.InternInfoRow - - -@Composable -fun HomeRecommendInternDialog( - internInfoList: List>, - clickAction: () -> Unit, - onColorSelected:(Color) -> Unit = {}, - homeRecommendIntern: HomeRecommendIntern, - viewModel: HomeViewModel = hiltViewModel(), -) { - val state by viewModel.homeDialogState.collectAsStateWithLifecycle() - - Box( - modifier = Modifier - .wrapContentSize() - .padding(top = 32.dp), - contentAlignment = Alignment.TopCenter - ) { - Column( - modifier = Modifier - .wrapContentSize() - .padding(horizontal = 11.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - AsyncImage( - model = ImageRequest.Builder(LocalContext.current) - .data(homeRecommendIntern.companyImage) - .build(), - contentDescription = stringResource(R.string.image_content_descriptin), - modifier = Modifier - .size(80.dp) - .border( - width = 1.dp, - color = TerningMain, - shape = RoundedCornerShape(size = 15.dp) - ) - .clip(RoundedCornerShape(size = 15.dp)), - contentScale = ContentScale.Fit, - alignment = Alignment.Center - ) - - Text( - text = homeRecommendIntern.title, - textAlign = TextAlign.Center, - style = TerningTheme.typography.title4, - color = Grey500, - modifier = Modifier.padding(top = 20.dp), - maxLines = 3, - overflow = TextOverflow.Ellipsis - ) - Text( - text = stringResource( - id = R.string.dialog_content_scrap_sub_title - ), - style = TerningTheme.typography.body5, - color = Grey350, - modifier = Modifier.padding( - top = 4.dp - ) - ) - Spacer(modifier = Modifier.height(26.dp)) - Column( - horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.Top, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 13.dp) - ) { - Row( - modifier = Modifier - .background( - color = state.selectedColor, - shape = RoundedCornerShape(14.dp) - ) - .noRippleClickable { - viewModel.updatePaletteOpen(!state.isPaletteOpen) - }, - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Start - ) { - Text( - text = stringResource(id = R.string.dialog_content_color_button), - style = TerningTheme.typography.body5, - color = White, - modifier = Modifier.padding( - start = 13.dp, - top = 5.dp, - bottom = 5.dp - ) - ) - Icon( - painter = painterResource( - id = if (state.isPaletteOpen) R.drawable.ic_up_22 - else R.drawable.ic_down_22 - ), - contentDescription = stringResource( - id = R.string.dialog_content_color_button - ), - tint = White, - modifier = Modifier.padding( - end = 7.dp - ) - ) - } - HorizontalDivider( - thickness = 1.dp, - color = Grey200, - modifier = Modifier.padding( - top = 11.dp, - bottom = 8.dp - ) - ) - if (state.isPaletteOpen) { - Box( - modifier = Modifier - .fillMaxWidth() - .padding( - top = 12.dp, - bottom = 23.dp, - ), - contentAlignment = Alignment.Center - ) { - ColorPalette( - initialColor = CalRed, - onColorSelected = { newColor -> - viewModel.updateSelectColor(newColor) - onColorSelected(newColor) - } - ) - } - } else { - Text( - text = homeRecommendIntern.dDay, - style = TerningTheme.typography.body5, - color = TerningMain, - modifier = Modifier.padding(bottom = 9.dp) - ) - Column( - modifier = Modifier.padding(bottom = 29.dp), - verticalArrangement = Arrangement.spacedBy( - 5.dp, - Alignment.CenterVertically - ), - horizontalAlignment = Alignment.Start, - ) { - internInfoList.forEach { - InternInfoRow( - title = it.first, - value = it.second - ) - } - } - } - } - Box( - modifier = Modifier.fillMaxWidth(), - contentAlignment = Alignment.BottomCenter - ) { - RoundButton( - style = TerningTheme.typography.button3, - paddingVertical = 12.dp, - cornerRadius = 8.dp, - text = R.string.dialog_scrap_button, - onButtonClick = { - clickAction() - }, - modifier = Modifier.padding(bottom = 8.dp) - ) - } - } - } -} \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayIntern.kt b/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayIntern.kt deleted file mode 100644 index d6c93b782..000000000 --- a/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayIntern.kt +++ /dev/null @@ -1,85 +0,0 @@ -package com.terning.feature.home.home.component - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -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.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel -import com.terning.core.designsystem.component.dialog.TerningBasicDialog -import com.terning.core.extension.noRippleClickable -import com.terning.domain.entity.home.HomeTodayIntern -import com.terning.feature.R -import com.terning.feature.home.home.HomeViewModel -import com.terning.feature.home.home.model.HomeDialogState - -@Composable -fun HomeTodayIntern( - internList: List, - homeDialogState: HomeDialogState, - navigateToIntern: (Long) -> Unit, - homeViewModel: HomeViewModel = hiltViewModel() -) { - var selectedIndex by remember { - mutableStateOf(0) - } - LazyRow( - horizontalArrangement = Arrangement.spacedBy(12.dp), - contentPadding = PaddingValues(horizontal = 24.dp), - modifier = Modifier - .fillMaxWidth(), - ) { - items(internList.size) { index -> - HomeTodayInternItem( - title = internList[index].title, - scrapColor = Color(android.graphics.Color.parseColor(internList[index].color)), - modifier = Modifier - .noRippleClickable { - homeViewModel.updateScrapDialogVisible(true) - homeViewModel.updateIsToday(true) - homeViewModel.updateSelectColor( - Color( - android.graphics.Color.parseColor( - internList[index].color - ) - ) - ) - selectedIndex = index - } - ) - } - } - - if (homeDialogState.isScrapDialogVisible && homeDialogState.isToday) { - TerningBasicDialog( - onDismissRequest = { - homeViewModel.updateScrapDialogVisible(false) - homeViewModel.updatePaletteOpen(false) - }, - content = { - with(internList[selectedIndex]) { - HomeTodayInternDialog( - internInfoList = listOf( - stringResource(id = R.string.intern_info_d_day) to deadline, - stringResource(id = R.string.intern_info_working) to workingPeriod, - stringResource(id = R.string.intern_info_start_date) to startYearMonth, - ), - navigateTo = { - navigateToIntern(internshipAnnouncementId) - homeViewModel.updateScrapDialogVisible(false) - }, - homeTodayIntern = internList[selectedIndex], - ) - } - }, - ) - } -} diff --git a/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayInternDialog.kt b/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayInternDialog.kt deleted file mode 100644 index cb6808de1..000000000 --- a/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayInternDialog.kt +++ /dev/null @@ -1,249 +0,0 @@ -package com.terning.feature.home.home.component - -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -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.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import coil.compose.AsyncImage -import coil.request.ImageRequest -import com.terning.core.R -import com.terning.core.designsystem.component.button.RoundButton -import com.terning.core.designsystem.component.item.ColorPalette -import com.terning.core.designsystem.theme.CalBlue1 -import com.terning.core.designsystem.theme.CalBlue2 -import com.terning.core.designsystem.theme.CalGreen1 -import com.terning.core.designsystem.theme.CalGreen2 -import com.terning.core.designsystem.theme.CalOrange1 -import com.terning.core.designsystem.theme.CalOrange2 -import com.terning.core.designsystem.theme.CalPink -import com.terning.core.designsystem.theme.CalPurple -import com.terning.core.designsystem.theme.CalRed -import com.terning.core.designsystem.theme.CalYellow -import com.terning.core.designsystem.theme.Grey200 -import com.terning.core.designsystem.theme.Grey350 -import com.terning.core.designsystem.theme.Grey500 -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.extension.noRippleClickable -import com.terning.domain.entity.home.HomeTodayIntern -import com.terning.feature.home.home.HomeViewModel -import com.terning.feature.intern.component.InternInfoRow - - -@Composable -fun HomeTodayInternDialog( - internInfoList: List>, - navigateTo: () -> Unit, - homeTodayIntern: HomeTodayIntern, - viewModel: HomeViewModel = hiltViewModel(), -) { - val state by viewModel.homeDialogState.collectAsStateWithLifecycle() - - val colorList = listOf( - CalRed, - CalOrange1, - CalOrange2, - CalYellow, - CalGreen1, - CalGreen2, - CalBlue1, - CalBlue2, - CalPurple, - CalPink, - ) - Column( - modifier = Modifier - .wrapContentSize() - .padding(start = 11.dp, end = 11.dp, top = 32.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - AsyncImage( - model = ImageRequest.Builder(LocalContext.current) - .data(homeTodayIntern.companyImage) - .build(), - contentDescription = stringResource(R.string.image_content_descriptin), - modifier = Modifier - .size(80.dp) - .border( - width = 1.dp, - color = TerningMain, - shape = RoundedCornerShape(size = 15.dp) - ) - .clip(RoundedCornerShape(size = 15.dp)), - contentScale = ContentScale.Fit, - alignment = Alignment.Center - ) - - Text( - text = homeTodayIntern.title, - textAlign = TextAlign.Center, - style = TerningTheme.typography.title4, - color = Grey500, - modifier = Modifier.padding(top = 20.dp), - maxLines = 3, - overflow = TextOverflow.Ellipsis - ) - Text( - text = stringResource( - id = R.string.dialog_today_deadline - ), - style = TerningTheme.typography.body5, - color = Grey350, - modifier = Modifier.padding( - top = 4.dp - ) - ) - Spacer(modifier = Modifier.height(26.dp)) - Column( - horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.Top, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 13.dp) - ) { - Row( - modifier = Modifier - .background( - color = state.selectedColor, - shape = RoundedCornerShape(14.dp) - ) - .noRippleClickable { - viewModel.updatePaletteOpen(!state.isPaletteOpen) - }, - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Start - ) { - Text( - text = stringResource(id = R.string.dialog_content_color_button), - style = TerningTheme.typography.body5, - color = White, - modifier = Modifier.padding( - start = 13.dp, - top = 5.dp, - bottom = 5.dp - ) - ) - Icon( - painter = painterResource( - id = if (state.isPaletteOpen) R.drawable.ic_up_22 - else R.drawable.ic_down_22 - ), - contentDescription = stringResource( - id = R.string.dialog_content_color_button - ), - tint = White, - modifier = Modifier.padding( - end = 7.dp - ) - ) - } - HorizontalDivider( - thickness = 1.dp, - color = Grey200, - modifier = Modifier.padding( - top = 11.dp, - bottom = 8.dp - ) - ) - if (state.isPaletteOpen) { - Box( - modifier = Modifier - .fillMaxWidth() - .padding( - top = 12.dp, - bottom = 23.dp, - ), - contentAlignment = Alignment.Center - ) { - ColorPalette( - initialColor = Color(android.graphics.Color.parseColor(homeTodayIntern.color)), - onColorSelected = { newColor -> - viewModel.updateSelectColor(newColor) - } - ) - } - } else { - Text( - text = homeTodayIntern.dDay, - style = TerningTheme.typography.body5, - color = TerningMain, - modifier = Modifier.padding(bottom = 9.dp) - ) - Column( - modifier = Modifier.padding(bottom = 29.dp), - verticalArrangement = Arrangement.spacedBy( - 5.dp, - Alignment.CenterVertically - ), - horizontalAlignment = Alignment.Start, - ) { - internInfoList.forEach { - InternInfoRow( - title = it.first, - value = it.second - ) - } - } - } - } - val selectedColorIndex = - colorList.indexOf(state.selectedColor).takeIf { it >= 0 } ?: 0 - - RoundButton( - style = TerningTheme.typography.button3, - paddingVertical = 12.dp, - cornerRadius = 8.dp, - text = if (state.isPaletteOpen) R.string.dialog_content_calendar_color_change else R.string.dialog_scrap_move_to_intern, - onButtonClick = { - if (state.isPaletteOpen) { - viewModel.updatePaletteOpen(false) - viewModel.updateColorChange(false) - viewModel.patchScrap( - scrapId = homeTodayIntern.scrapId, - colorIndex = selectedColorIndex, - ) - } else { - if (state.isColorChange) { - viewModel.updateColorChange(false) - viewModel.patchScrap( - scrapId = homeTodayIntern.scrapId, - colorIndex = selectedColorIndex, - ) - } - viewModel.updateScrapDialogVisible(false) - navigateTo() - } - }, - modifier = Modifier.padding(bottom = 8.dp) - ) - } -} - diff --git a/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayInternItem.kt b/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayInternItem.kt deleted file mode 100644 index f97e42b1d..000000000 --- a/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayInternItem.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.terning.feature.home.home.component - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import com.terning.core.designsystem.component.item.ScrapBox -import com.terning.core.designsystem.theme.Black -import com.terning.core.designsystem.theme.Grey150 -import com.terning.core.designsystem.theme.TerningTheme - -@Composable -fun HomeTodayInternItem( - title: String, - scrapColor: Color, - modifier: Modifier = Modifier -) { - ScrapBox( - modifier = modifier - .height(116.dp) - .width(140.dp), - cornerRadius = 5.dp, - scrapColor = scrapColor, - borderWidth = 1.dp, - borderColor = Grey150, - content = { - Column( - modifier = modifier - .fillMaxHeight(), - verticalArrangement = Arrangement.Bottom - ) { - Text( - text = title, - modifier = modifier - .padding( - start = 8.dp, - end = 9.dp, - bottom = 8.dp - ), - style = TerningTheme.typography.button3, - color = Black, - maxLines = 3, - ) - } - } - ) -} \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayEmptyWithImg.kt b/feature/src/main/java/com/terning/feature/home/home/component/HomeUpcomingEmptyFilter.kt similarity index 93% rename from feature/src/main/java/com/terning/feature/home/home/component/HomeTodayEmptyWithImg.kt rename to feature/src/main/java/com/terning/feature/home/home/component/HomeUpcomingEmptyFilter.kt index 2d681f98d..11de75c49 100644 --- a/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayEmptyWithImg.kt +++ b/feature/src/main/java/com/terning/feature/home/home/component/HomeUpcomingEmptyFilter.kt @@ -23,7 +23,7 @@ import com.terning.core.extension.customShadow import com.terning.feature.R @Composable -fun HomeTodayEmptyWithImg( +fun HomeUpcomingEmptyFilter( modifier: Modifier = Modifier, ) { Column( @@ -49,8 +49,8 @@ fun HomeTodayEmptyWithImg( .padding(top = 24.dp) ) Text( - text = stringResource(id = R.string.home_scrap_empty), - modifier = modifier + text = stringResource(id = R.string.home_upcoming_no_scrap), + modifier = Modifier .padding(top = 8.dp, bottom = 25.dp) .fillMaxWidth() .wrapContentWidth(Alignment.CenterHorizontally), diff --git a/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayEmptyIntern.kt b/feature/src/main/java/com/terning/feature/home/home/component/HomeUpcomingEmptyIntern.kt similarity index 53% rename from feature/src/main/java/com/terning/feature/home/home/component/HomeTodayEmptyIntern.kt rename to feature/src/main/java/com/terning/feature/home/home/component/HomeUpcomingEmptyIntern.kt index f714c3abe..863488adc 100644 --- a/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayEmptyIntern.kt +++ b/feature/src/main/java/com/terning/feature/home/home/component/HomeUpcomingEmptyIntern.kt @@ -5,7 +5,6 @@ import androidx.compose.foundation.border import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults @@ -19,15 +18,17 @@ import androidx.compose.ui.unit.dp import com.terning.core.designsystem.theme.Grey200 import com.terning.core.designsystem.theme.Grey400 import com.terning.core.designsystem.theme.Grey500 +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.extension.customShadow +import com.terning.core.extension.noRippleClickable import com.terning.feature.R @Composable -fun HomeTodayEmptyIntern( - isButtonExist: Boolean, +fun HomeUpcomingEmptyIntern( modifier: Modifier = Modifier, + navigateToCalendar: () -> Unit, ) { Column( modifier = modifier @@ -44,50 +45,38 @@ fun HomeTodayEmptyIntern( shape = RoundedCornerShape(5.dp) ) ) { - if (isButtonExist) { - Column( + Column( + modifier = modifier + .fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = stringResource(id = R.string.home_upcoming_empty), modifier = modifier - .fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, + .padding(top = 27.dp), + textAlign = TextAlign.Center, + style = TerningTheme.typography.detail3, + color = Grey500, + ) + Card( + colors = CardDefaults.cardColors(White), + modifier = modifier + .padding(top = 8.dp, bottom = 27.dp) + .border( + width = 1.dp, + color = TerningMain, + shape = RoundedCornerShape(12.dp), + ) + .noRippleClickable(navigateToCalendar), ) { Text( - text = stringResource(id = R.string.home_today_no_closed), + text = stringResource(id = R.string.home_upcoming_check_schedule), + style = TerningTheme.typography.button4, + color = TerningMain, modifier = modifier - .padding(top = 27.dp), - textAlign = TextAlign.Center, - style = TerningTheme.typography.detail3, - color = Grey500, + .padding(vertical = 8.dp, horizontal = 10.dp) ) - Card( - colors = CardDefaults.cardColors(White), - modifier = modifier - .padding(top = 7.dp, bottom = 27.dp) - .border( - width = 1.dp, - color = Grey400, - shape = RoundedCornerShape(12.dp), - ), - ) { - Text( - text = stringResource(id = R.string.home_today_check_schedule), - style = TerningTheme.typography.button4, - color = Grey400, - modifier = modifier - .padding(vertical = 8.dp, horizontal = 10.dp) - ) - } } - } else { - Text( - text = stringResource(id = R.string.home_today_no_scrap), - modifier = modifier - .padding(vertical = 44.dp) - .fillMaxWidth() - .wrapContentWidth(Alignment.CenterHorizontally), - textAlign = TextAlign.Center, - style = TerningTheme.typography.detail2, - color = Grey500, - ) } } } \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/home/component/HomeUpcomingInternScreen.kt b/feature/src/main/java/com/terning/feature/home/home/component/HomeUpcomingInternScreen.kt new file mode 100644 index 000000000..a0bdbf50c --- /dev/null +++ b/feature/src/main/java/com/terning/feature/home/home/component/HomeUpcomingInternScreen.kt @@ -0,0 +1,182 @@ +package com.terning.feature.home.home.component + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxHeight +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.lazy.LazyRow +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +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.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import coil.compose.AsyncImage +import coil.request.ImageRequest +import com.terning.core.designsystem.component.item.ScrapBox +import com.terning.core.designsystem.theme.Black +import com.terning.core.designsystem.theme.Grey150 +import com.terning.core.designsystem.theme.Grey500 +import com.terning.core.designsystem.theme.TerningMain +import com.terning.core.designsystem.theme.TerningSub3 +import com.terning.core.designsystem.theme.TerningTheme +import com.terning.core.extension.noRippleClickable +import com.terning.domain.entity.home.HomeUpcomingIntern +import com.terning.feature.R +import com.terning.feature.dialog.detail.ScrapDialog +import com.terning.feature.home.home.HomeState +import com.terning.feature.home.home.HomeViewModel + +@Composable +fun HomeUpcomingInternScreen( + internList: List, + homeState: HomeState, + navigateToIntern: (Long) -> Unit, + homeViewModel: HomeViewModel = hiltViewModel() +) { + var selectedInternItem: HomeUpcomingIntern? by remember { + mutableStateOf(null) + } + + LazyRow( + horizontalArrangement = Arrangement.spacedBy(12.dp), + contentPadding = PaddingValues(horizontal = 24.dp), + modifier = Modifier + .fillMaxWidth(), + ) { + items(internList.size) { index -> + val homeUpcomingIntern = internList[index] + + ScrapBox( + modifier = Modifier + .width(246.dp), + cornerRadius = 5.dp, + scrapColor = Color(android.graphics.Color.parseColor(homeUpcomingIntern.color)), + borderWidth = 1.dp, + borderColor = Grey150, + content = { + Column( + modifier = Modifier + .fillMaxHeight() + .noRippleClickable { + selectedInternItem = homeUpcomingIntern + homeViewModel.updateUpcomingDialogVisibility(true) + }, + verticalArrangement = Arrangement.SpaceBetween, + ) { + Text( + text = homeUpcomingIntern.title, + modifier = Modifier + .padding( + start = 12.dp, + end = 12.dp, + top = 16.dp + ), + style = TerningTheme.typography.button3, + color = Black, + maxLines = 3, + minLines = 3, + ) + + Row( + modifier = Modifier + .padding( + start = 12.dp, + end = 12.dp, + bottom = 12.dp, + top = 8.dp + ) + .fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + AsyncImage( + model = ImageRequest.Builder(LocalContext.current) + .data(homeUpcomingIntern.companyImage) + .build(), + contentDescription = stringResource(id = R.string.home_company_image), + contentScale = ContentScale.Crop, + modifier = Modifier + .height(32.dp) + .aspectRatio(1f) + .border(BorderStroke(1.dp, Grey150), CircleShape) + .clip(CircleShape) + ) + + Text( + text = "유한킴벌리", + style = TerningTheme.typography.button5, + color = Grey500, + maxLines = 1, + modifier = Modifier + .padding(start = 6.dp, end = 15.dp) + .weight(1f) + ) + + Row( + modifier = Modifier + .size(width = 40.dp, height = 20.dp) + .background( + color = TerningSub3, + shape = RoundedCornerShape(size = 5.dp) + ), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = homeUpcomingIntern.dDay, + style = TerningTheme.typography.body4, + color = TerningMain, + ) + } + } + } + } + ) + } + } + + if (homeState.homeUpcomingDialogVisibility) { + val upcomingIntern = selectedInternItem + with(upcomingIntern) { + if (this != null) { + ScrapDialog( + title = title, + scrapColor = Color(android.graphics.Color.parseColor(color)), + deadline = deadline, + startYearMonth = startYearMonth, + workingPeriod = workingPeriod, + internshipAnnouncementId = internshipAnnouncementId, + companyImage = companyImage, + isScrapped = isScrapped, + onDismissRequest = { + homeViewModel.updateUpcomingDialogVisibility(false) + }, + onClickChangeColor = { }, + onClickNavigateButton = { navigateToIntern(internshipAnnouncementId) } + ) + } + } + } +} diff --git a/feature/src/main/java/com/terning/feature/home/home/model/SortBy.kt b/feature/src/main/java/com/terning/feature/home/home/model/SortBy.kt deleted file mode 100644 index b820cd6ca..000000000 --- a/feature/src/main/java/com/terning/feature/home/home/model/SortBy.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.terning.feature.home.home.model - -enum class SortBy(val sortBy: String) { - EARLIEST("deadlineSoon"), - SHORTEST("shortestDuration"), - LONGEST("longestDuration"), - SCRAP("mostScrapped"), - VIEW_COUNT("mostViewed"), -} \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/main/MainScreen.kt b/feature/src/main/java/com/terning/feature/main/MainScreen.kt index f851101a2..1a5a56605 100644 --- a/feature/src/main/java/com/terning/feature/main/MainScreen.kt +++ b/feature/src/main/java/com/terning/feature/main/MainScreen.kt @@ -43,7 +43,6 @@ import com.terning.feature.filtering.filtering.navigation.filteringTwoNavGraph import com.terning.feature.filtering.filteringthree.navigation.filteringThreeNavGraph import com.terning.feature.filtering.startfiltering.navigation.startFilteringNavGraph import com.terning.feature.filtering.starthome.navigation.startHomeNavGraph -import com.terning.feature.home.changefilter.navigation.changeFilterNavGraph import com.terning.feature.home.home.navigation.homeNavGraph import com.terning.feature.intern.navigation.internNavGraph import com.terning.feature.mypage.mypage.navigation.myPageNavGraph @@ -161,7 +160,6 @@ fun MainScreen( navHostController = navigator.navController ) searchProcessNavGraph(navHostController = navigator.navController) - changeFilterNavGraph(navHostController = navigator.navController) internNavGraph(navHostController = navigator.navController) myPageNavGraph( paddingValues = paddingValues, diff --git a/feature/src/main/res/values/strings.xml b/feature/src/main/res/values/strings.xml index 60d721208..3af17bc8b 100644 --- a/feature/src/main/res/values/strings.xml +++ b/feature/src/main/res/values/strings.xml @@ -70,14 +70,12 @@ 관심 공고가 캘린더에서 사라졌어요! - 오늘 마감되는 %s님의 관심 공고 - 아직 스크랩된 인턴 공고가 없어요!\n관심 공고를 스크랩하면 마감 당일에 알려드릴게요 - 오늘 마감인 공고가 없어요\n캘린더에서 가까운 공고 일정을 확인해 보세요 - 공고 마감 일정 확인하기 + 곧 마감되는 %s님의 관심 공고 + 아직 스크랩된 인턴 공고가 없어요! + 오늘 마감인 공고가 없어요\n캘린더에서 가까운 공고 일정을 확인해 보세요 + 공고 마감 일정 확인하기 - D- 근무기간 - 마음에 드는 공고를 스크랩하고 캘린더에서 모아보세요 내 계획에 딱 맞는 대학생 인턴 공고 필터링 학년 @@ -88,8 +86,11 @@ 지금 공고 필터링을 설정하고\n내 계획에 딱 맞는 대학생 인턴 공고를 추천받아보세요! - - - 오늘 마감인 공고가 없어요 + + 개의 공고가 있어요 + 설정된 필터링 정보가 없어요 + + 기업 이미지 터치 3번으로\n원하는 대학생 인턴 공고를 띄워드릴게요 @@ -126,8 +127,17 @@ 필터링 재설정 - 재학 상태를 선택해 주세요 + 재학 상태 저장하기 + 1학년 + 2학년 + 3학년 + 4학년 + 희망 근무 기간 + 1개월 ~ 3개월 + 4개월 ~ 6개월 + 7개월 이상 + 근무 시작 시기 공유 아이콘