diff --git a/core/src/main/java/com/terning/core/designsystem/component/item/InternItemWithShadow.kt b/core/src/main/java/com/terning/core/designsystem/component/item/InternItemWithShadow.kt index 287e4076d..cc0f59122 100644 --- a/core/src/main/java/com/terning/core/designsystem/component/item/InternItemWithShadow.kt +++ b/core/src/main/java/com/terning/core/designsystem/component/item/InternItemWithShadow.kt @@ -22,6 +22,7 @@ fun InternItemWithShadow( dateDeadline: String, workingPeriod: String, isScrapped: Boolean, + onScrapButtonClicked: (Long) -> Unit = {} ) { Box( modifier = modifier @@ -40,7 +41,8 @@ fun InternItemWithShadow( title = title, dateDeadline = dateDeadline, workingPeriod = workingPeriod, - isScraped = isScrapped + isScraped = isScrapped, + onScrapButtonClicked = onScrapButtonClicked ) } } \ 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 23ac42201..71380b12d 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -52,6 +52,7 @@ 스크랩 취소하기 내가 스크랩한 관심 공고에요! 공고 상세 정보 보러가기 + 오늘 마감되는 공고예요! 서류 마감 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 7793aa0ee..008315cc7 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 @@ -6,14 +6,20 @@ 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") @@ -21,10 +27,13 @@ data class HomeRecommendInternResponseDto( ) { 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, ) diff --git a/domain/src/main/java/com/terning/domain/entity/response/HomeRecommendInternModel.kt b/domain/src/main/java/com/terning/domain/entity/response/HomeRecommendInternModel.kt index 18772bc92..5b1b23ce0 100644 --- a/domain/src/main/java/com/terning/domain/entity/response/HomeRecommendInternModel.kt +++ b/domain/src/main/java/com/terning/domain/entity/response/HomeRecommendInternModel.kt @@ -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, ) 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 580ed6c9f..bc437e7a4 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 @@ -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 @@ -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 @@ -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) @@ -146,6 +151,7 @@ fun HomeRoute( homeFilteringInfo = homeFilteringInfo, homeTodayInternList = homeTodayInternList, recommendInternList = homeRecommendInternList, + homeDialogState = homeDialogState, onChangeFilterClick = { navController.navigateChangeFilter() }, navController = navController ) @@ -159,11 +165,13 @@ fun HomeScreen( homeFilteringInfo: HomeFilteringInfoModel, homeTodayInternList: List, recommendInternList: List, + homeDialogState: HomeDialogState, onChangeFilterClick: () -> Unit, viewModel: HomeViewModel = hiltViewModel(), navController: NavHostController, ) { var sheetState by remember { mutableStateOf(false) } + var scrapId by remember { mutableStateOf(-1) } if (sheetState) { SortingBottomSheet( @@ -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 { @@ -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 + } ) } } @@ -256,6 +273,54 @@ 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, + ) + } + } + } + ) + } } @@ -263,6 +328,7 @@ fun HomeScreen( private fun RecommendInternItem( navController: NavHostController, intern: HomeRecommendInternModel, + onScrapButtonClicked: (Long) -> Unit, ) { InternItemWithShadow( modifier = Modifier @@ -278,7 +344,8 @@ private fun RecommendInternItem( workingPeriod = intern.workingPeriod, isScrapped = intern.isScrapped, shadowRadius = 5.dp, - shadowWidth = 1.dp + shadowWidth = 1.dp, + onScrapButtonClicked = onScrapButtonClicked, ) } @@ -299,11 +366,19 @@ private fun ShowMainTitleWithName(userName: String) { } @Composable -private fun ShowTodayIntern(homeTodayInternList: List) { +private fun ShowTodayIntern( + homeTodayInternList: List, + homeDialogState: HomeDialogState, + navigateToDetail: (Long) -> Unit, +) { if (homeTodayInternList.isEmpty()) { HomeTodayEmptyWithImg() } else { - HomeTodayIntern(internList = homeTodayInternList) + HomeTodayIntern( + internList = homeTodayInternList, + homeDialogState = homeDialogState, + navigateToDetail = { navigateToDetail(it) }, + ) } } 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 23c813f3e..f0764e7f0 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,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 @@ -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) @@ -49,6 +55,10 @@ class HomeViewModel @Inject constructor( private val _homeUserState = MutableStateFlow>(UiState.Loading) val homeUserState get() = _homeUserState.asStateFlow() + private val _homeDialogState: MutableStateFlow = + MutableStateFlow(HomeDialogState()) + val homeDialogState get() = _homeDialogState.asStateFlow() + init { getProfile() getFilteringInfo() @@ -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) + } + } } \ 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 new file mode 100644 index 000000000..45e08b4ba --- /dev/null +++ b/feature/src/main/java/com/terning/feature/home/home/component/HomeRecommendInternDialog.kt @@ -0,0 +1,258 @@ +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.fillMaxSize +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.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.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.response.HomeRecommendInternModel +import com.terning.feature.home.home.HomeViewModel +import com.terning.feature.intern.component.InternInfoRow + + +@Composable +fun HomeRecommendInternDialog( + internInfoList: List>, + clickAction: () -> Unit, + homeRecommendInternModel: HomeRecommendInternModel, + viewModel: HomeViewModel = hiltViewModel(), +) { + val state by viewModel.homeDialogState.collectAsStateWithLifecycle() + + val colorList = listOf( + CalRed, + CalOrange1, + CalOrange2, + CalYellow, + CalGreen1, + CalGreen2, + CalBlue1, + CalBlue2, + CalPurple, + CalPink, + ) + + Box( + modifier = Modifier + .fillMaxSize() + .padding(top = 32.dp), + contentAlignment = Alignment.TopCenter + ) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 11.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + AsyncImage( + model = ImageRequest.Builder(LocalContext.current) + .data(homeRecommendInternModel.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 = homeRecommendInternModel.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) + } + ) + } + } else { + Text( + text = homeRecommendInternModel.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 + ) + } + } + } + } + Spacer(modifier = Modifier.weight(1f)) + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = Alignment.BottomCenter + ) { + val selectedColorIndex = + colorList.indexOf(state.selectedColor).takeIf { it >= 0 } ?: 0 + + RoundButton( + style = TerningTheme.typography.button3, + paddingVertical = 12.dp, + cornerRadius = 8.dp, + text = R.string.dialog_scrap_button, + onButtonClick = { + if (state.isPaletteOpen) { + viewModel.updatePaletteOpen(false) + viewModel.updateColorChange(false) + viewModel.updateScrapDialogVisible(false) + } else { + if (state.isColorChange) { + viewModel.updateColorChange(false) + } + viewModel.updateScrapDialogVisible(false) + } + viewModel.postScrap( + homeRecommendInternModel.internshipAnnouncementId, + selectedColorIndex, + ) + 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 index 790859ae8..fac68b5ed 100644 --- 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 @@ -5,13 +5,32 @@ 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.response.HomeTodayInternModel +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) { +fun HomeTodayIntern( + internList: List, + homeDialogState: HomeDialogState, + navigateToDetail: (Long) -> Unit, + homeViewModel: HomeViewModel = hiltViewModel() +) { + var selectedIndex by remember { + mutableStateOf(0) + } LazyRow( horizontalArrangement = Arrangement.spacedBy(12.dp), contentPadding = PaddingValues(horizontal = 24.dp), @@ -21,8 +40,38 @@ fun HomeTodayIntern(internList: List) { items(internList.size) { index -> HomeTodayInternItem( title = internList[index].title, - scrapColor = Color(android.graphics.Color.parseColor(internList[index].color)) + scrapColor = Color(android.graphics.Color.parseColor(internList[index].color)), + modifier = Modifier + .noRippleClickable { + homeViewModel.updateScrapDialogVisible(true) + homeViewModel.updateIsToday(true) + selectedIndex = index + } ) } } + + if (homeDialogState.isScrapDialogVisible && homeDialogState.isToday) { + TerningBasicDialog( + onDismissRequest = { + homeViewModel.updateScrapDialogVisible(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 = { + navigateToDetail(internshipAnnouncementId) + homeViewModel.updateScrapDialogVisible(false) + }, + homeTodayInternModel = 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 new file mode 100644 index 000000000..5fee0d572 --- /dev/null +++ b/feature/src/main/java/com/terning/feature/home/home/component/HomeTodayInternDialog.kt @@ -0,0 +1,254 @@ +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.fillMaxSize +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.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.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.response.HomeTodayInternModel +import com.terning.feature.home.home.HomeViewModel +import com.terning.feature.intern.component.InternInfoRow + + +@Composable +fun HomeTodayInternDialog( + internInfoList: List>, + navigateTo: () -> Unit, + homeTodayInternModel: HomeTodayInternModel, + viewModel: HomeViewModel = hiltViewModel(), +) { + val state by viewModel.homeDialogState.collectAsStateWithLifecycle() + + val colorList = listOf( + CalRed, + CalOrange1, + CalOrange2, + CalYellow, + CalGreen1, + CalGreen2, + CalBlue1, + CalBlue2, + CalPurple, + CalPink, + ) + + Box( + modifier = Modifier + .fillMaxSize() + .padding(top = 32.dp), + contentAlignment = Alignment.TopCenter + ) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 11.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + AsyncImage( + model = ImageRequest.Builder(LocalContext.current) + .data(homeTodayInternModel.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 = homeTodayInternModel.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 = CalRed, + onColorSelected = { newColor -> + viewModel.updateSelectColor(newColor) + } + ) + } + } else { + Text( + text = homeTodayInternModel.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 + ) + } + } + } + } + Spacer(modifier = Modifier.weight(1f)) + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = Alignment.BottomCenter + ) { + val selectedColorIndex = + colorList.indexOf(state.selectedColor).takeIf { it >= 0 } ?: 0 + + RoundButton( + style = TerningTheme.typography.button3, + paddingVertical = 12.dp, + cornerRadius = 8.dp, + text = R.string.dialog_scrap_move_to_intern, + onButtonClick = { + if (state.isPaletteOpen) { + viewModel.updatePaletteOpen(false) + viewModel.updateColorChange(false) + viewModel.updateScrapDialogVisible(false) + } else { + if (state.isColorChange) { + viewModel.updateColorChange(false) + } + viewModel.updateScrapDialogVisible(false) + } + navigateTo() + }, + modifier = Modifier.padding(bottom = 8.dp) + ) + } + } + } +} \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/home/home/model/HomeDialogState.kt b/feature/src/main/java/com/terning/feature/home/home/model/HomeDialogState.kt new file mode 100644 index 000000000..2df1a7ca3 --- /dev/null +++ b/feature/src/main/java/com/terning/feature/home/home/model/HomeDialogState.kt @@ -0,0 +1,13 @@ +package com.terning.feature.home.home.model + +import androidx.compose.ui.graphics.Color +import com.terning.core.designsystem.theme.CalRed + +data class HomeDialogState( + val isColorChange: Boolean = false, + val isPaletteOpen: Boolean = false, + val selectedColor: Color = CalRed, + val isScrapDialogVisible: Boolean = false, + val isScrappedState: Boolean = false, + val isToday: Boolean = false, +) \ No newline at end of file