Skip to content

Commit

Permalink
[MERGE] #146 -> develop
Browse files Browse the repository at this point in the history
[UI#146] 홈 뷰 / 다이얼로그 구현
  • Loading branch information
Hyobeen-Park authored Jul 18, 2024
2 parents d17a16b + 19ae5cf commit 316f7dd
Show file tree
Hide file tree
Showing 10 changed files with 752 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ fun InternItemWithShadow(
dateDeadline: String,
workingPeriod: String,
isScrapped: Boolean,
onScrapButtonClicked: (Long) -> Unit = {}
) {
Box(
modifier = modifier
Expand All @@ -40,7 +41,8 @@ fun InternItemWithShadow(
title = title,
dateDeadline = dateDeadline,
workingPeriod = workingPeriod,
isScraped = isScrapped
isScraped = isScrapped,
onScrapButtonClicked = onScrapButtonClicked
)
}
}
1 change: 1 addition & 0 deletions core/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
<string name="dialog_scrap_cancel_button">스크랩 취소하기</string>
<string name="dialog_scrap_mine">내가 스크랩한 관심 공고에요!</string>
<string name="dialog_scrap_move_to_intern">공고 상세 정보 보러가기</string>
<string name="dialog_today_deadline">오늘 마감되는 공고예요!</string>

<!--Intern-->
<string name="intern_info_d_day">서류 마감</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,34 @@ 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,
) {
fun toRecommendInternEntity(): HomeRecommendInternModel =
HomeRecommendInternModel(
scrapId = this.scrapId,
internshipAnnouncementId = this.internshipAnnouncementId,
title = this.title,
dDay = this.dDay,
deadline = deadline,
workingPeriod = this.workingPeriod,
startYearMonth = this.startYearMonth,
companyImage = this.companyImage,
isScrapped = this.isScrapped,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.terning.domain.entity.response

data class HomeRecommendInternModel(
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,
)
85 changes: 80 additions & 5 deletions feature/src/main/java/com/terning/feature/home/home/HomeRoute.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ 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.item.InternItemWithShadow
import com.terning.core.designsystem.component.topappbar.LogoTopAppBar
import com.terning.core.designsystem.theme.Black
Expand All @@ -52,8 +54,10 @@ import com.terning.feature.home.changefilter.navigation.navigateChangeFilter
import com.terning.feature.home.home.component.HomeFilteringEmptyIntern
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.navigation.navigateHome
import com.terning.feature.intern.navigation.navigateIntern

Expand Down Expand Up @@ -87,6 +91,7 @@ fun HomeRoute(
val homeRecommendInternState by viewModel.homeRecommendInternState.collectAsStateWithLifecycle()
val homeFilteringState by viewModel.homeFilteringState.collectAsStateWithLifecycle()
val homeUserState by viewModel.homeUserState.collectAsStateWithLifecycle()
val homeDialogState by viewModel.homeDialogState.collectAsStateWithLifecycle()

LaunchedEffect(viewModel.homeSideEffect, lifecycleOwner) {
viewModel.homeSideEffect.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle)
Expand Down Expand Up @@ -146,6 +151,7 @@ fun HomeRoute(
homeFilteringInfo = homeFilteringInfo,
homeTodayInternList = homeTodayInternList,
recommendInternList = homeRecommendInternList,
homeDialogState = homeDialogState,
onChangeFilterClick = { navController.navigateChangeFilter() },
navController = navController
)
Expand All @@ -159,11 +165,13 @@ fun HomeScreen(
homeFilteringInfo: HomeFilteringInfoModel,
homeTodayInternList: List<HomeTodayInternModel>,
recommendInternList: List<HomeRecommendInternModel>,
homeDialogState: HomeDialogState,
onChangeFilterClick: () -> Unit,
viewModel: HomeViewModel = hiltViewModel(),
navController: NavHostController,
) {
var sheetState by remember { mutableStateOf(false) }
var scrapId by remember { mutableStateOf(-1) }

if (sheetState) {
SortingBottomSheet(
Expand Down Expand Up @@ -199,7 +207,11 @@ fun HomeScreen(
.padding(bottom = 16.dp)
) {
ShowMainTitleWithName(homeUserName)
ShowTodayIntern(homeTodayInternList = homeTodayInternList)
ShowTodayIntern(
homeTodayInternList = homeTodayInternList,
homeDialogState = homeDialogState,
navigateToDetail = { navController.navigateIntern(announcementId = it) }
)
}
}
stickyHeader {
Expand Down Expand Up @@ -239,7 +251,12 @@ fun HomeScreen(
items(recommendInternList.size) { index ->
RecommendInternItem(
navController = navController,
intern = recommendInternList[index]
intern = recommendInternList[index],
onScrapButtonClicked = {
viewModel.updateScrapDialogVisible(true)
viewModel.updateIsToday(false)
scrapId = index
}
)
}
}
Expand All @@ -256,13 +273,62 @@ fun HomeScreen(
}
}
}

if (homeDialogState.isScrapDialogVisible && !homeDialogState.isToday) {
TerningBasicDialog(
onDismissRequest = { viewModel.updateScrapDialogVisible(false) },
content = {
if (recommendInternList[scrapId].scrapId != null) {
ScrapCancelDialogContent(
onClickScrapCancel = {
viewModel.updateScrapDialogVisible(false)
viewModel.deleteScrap(
recommendInternList[scrapId].scrapId ?: -1,
)
if(homeDialogState.isScrappedState) {
viewModel.getRecommendInternsData(
currentSortBy.value,
homeFilteringInfo.startYear ?: viewModel.currentYear,
homeFilteringInfo.startMonth ?: viewModel.currentMonth,
)
viewModel.updateScrapped(false)
}
}
)
} else {
with(recommendInternList[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 = {
viewModel.updateScrapDialogVisible(false)
if(homeDialogState.isScrappedState) {
viewModel.getRecommendInternsData(
currentSortBy.value,
homeFilteringInfo.startYear ?: viewModel.currentYear,
homeFilteringInfo.startMonth ?: viewModel.currentMonth,
)
viewModel.updateScrapped(false)
}
},
homeRecommendInternModel = this,
)
}
}
}
)
}
}


@Composable
private fun RecommendInternItem(
navController: NavHostController,
intern: HomeRecommendInternModel,
onScrapButtonClicked: (Long) -> Unit,
) {
InternItemWithShadow(
modifier = Modifier
Expand All @@ -278,7 +344,8 @@ private fun RecommendInternItem(
workingPeriod = intern.workingPeriod,
isScrapped = intern.isScrapped,
shadowRadius = 5.dp,
shadowWidth = 1.dp
shadowWidth = 1.dp,
onScrapButtonClicked = onScrapButtonClicked,
)
}

Expand All @@ -299,11 +366,19 @@ private fun ShowMainTitleWithName(userName: String) {
}

@Composable
private fun ShowTodayIntern(homeTodayInternList: List<HomeTodayInternModel>) {
private fun ShowTodayIntern(
homeTodayInternList: List<HomeTodayInternModel>,
homeDialogState: HomeDialogState,
navigateToDetail: (Long) -> Unit,
) {
if (homeTodayInternList.isEmpty()) {
HomeTodayEmptyWithImg()
} else {
HomeTodayIntern(internList = homeTodayInternList)
HomeTodayIntern(
internList = homeTodayInternList,
homeDialogState = homeDialogState,
navigateToDetail = { navigateToDetail(it) },
)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
package com.terning.feature.home.home

import androidx.compose.ui.graphics.Color
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.terning.core.state.UiState
import com.terning.domain.entity.request.ChangeFilteringRequestModel
import com.terning.domain.entity.request.ScrapRequestModel
import com.terning.domain.entity.response.HomeFilteringInfoModel
import com.terning.domain.entity.response.HomeRecommendInternModel
import com.terning.domain.entity.response.HomeTodayInternModel
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
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import java.util.Calendar
import javax.inject.Inject
Expand All @@ -24,6 +29,7 @@ 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)
Expand All @@ -49,6 +55,10 @@ class HomeViewModel @Inject constructor(
private val _homeUserState = MutableStateFlow<UiState<String>>(UiState.Loading)
val homeUserState get() = _homeUserState.asStateFlow()

private val _homeDialogState: MutableStateFlow<HomeDialogState> =
MutableStateFlow(HomeDialogState())
val homeDialogState get() = _homeDialogState.asStateFlow()

init {
getProfile()
getFilteringInfo()
Expand Down Expand Up @@ -112,4 +122,74 @@ class HomeViewModel @Inject constructor(
}
}
}

fun postScrap(
internshipAnnouncementId: Long,
colorIndex: Int,
) {
viewModelScope.launch {
scrapRepository.postScrap(
ScrapRequestModel(
id = internshipAnnouncementId,
color = colorIndex,
)
).onSuccess {
updateScrapDialogVisible(visible = false)
updateScrapped(scrapped = true)
getHomeTodayInternList()
}.onFailure {
_homeSideEffect.emit(HomeSideEffect.ShowToast(R.string.server_failure))
}
}
}

fun deleteScrap(scrapId: Long) {
viewModelScope.launch {
scrapRepository.deleteScrap(
ScrapRequestModel(id = scrapId)
).onSuccess {
updateScrapDialogVisible(visible = false)
updateScrapped(scrapped = true)
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)
}
}
}
Loading

0 comments on commit 316f7dd

Please sign in to comment.