From 502d450107a2a5f054457c69955052ddf651e8b5 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Sun, 19 May 2024 12:08:49 +0900 Subject: [PATCH 01/19] =?UTF-8?q?[feat]=20splash=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=EB=B0=A9=EC=8B=9D=20=EB=8B=A8=EC=88=9C?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/remind/app/RemindNavHost.kt | 1 - .../screens/auth/login/LoginViewModel.kt | 2 +- .../screens/auth/splash/SplashScreen.kt | 1 + .../screens/auth/splash/SplashViewModel.kt | 49 +++---------------- 4 files changed, 9 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/com/example/remind/app/RemindNavHost.kt b/app/src/main/java/com/example/remind/app/RemindNavHost.kt index fb7b041..b0dfbed 100644 --- a/app/src/main/java/com/example/remind/app/RemindNavHost.kt +++ b/app/src/main/java/com/example/remind/app/RemindNavHost.kt @@ -24,7 +24,6 @@ fun RemindNavHost() { } DoctorGraph(navHostController) CenterGraph(navHostController) - //WritingGraph(navHostController) } } diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginViewModel.kt index 269fab3..309ad59 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginViewModel.kt @@ -95,7 +95,7 @@ private fun socialLogin(token: String) { Timber.d("${tokenManager.getAccessToken()} ||| ${tokenManager.getRefreshToken()}") } is ApiResult.Failure.UnknownApiError -> { - postEffect(LoginContract.Effect.Toastmessage("리마인드 서버 관리자에게 문의하세요")) + postEffect(LoginContract.Effect.Toastmessage("리마인드 고객센터에 문의하세요")) } is ApiResult.Failure.NetworkError -> { postEffect(LoginContract.Effect.Toastmessage("네트워크 설정을 확인해주세요")) diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/splash/SplashScreen.kt b/app/src/main/java/com/example/remind/feature/screens/auth/splash/SplashScreen.kt index ae876eb..0f088f3 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/splash/SplashScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/splash/SplashScreen.kt @@ -59,6 +59,7 @@ fun SplashScreen( is SplashContract.Effect.NavigateTo -> { navController.navigate(effect.destination, effect.navOptions) } + else -> {} } } } diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/splash/SplashViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/auth/splash/SplashViewModel.kt index 8b6b662..1a77fe4 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/splash/SplashViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/splash/SplashViewModel.kt @@ -33,60 +33,25 @@ class SplashViewModel @Inject constructor( fun checkUserState() { val userType = currentState.userType when(userType) { - "ROLE_DOCTOR" -> navigateToDoctor() - "ROLE_CENTER" -> navigateToCenter() - "ROLE_PATIENT" -> navigateToPatience() - else -> navigateToLogin() + "ROLE_DOCTOR" -> navigateToRoute(Screens.Doctor.DoctorMain.route, Screens.Splash.SplashScreen.route) + "ROLE_CENTER" -> navigateToRoute(Screens.Center.CenterMain.route, Screens.Splash.SplashScreen.route) + "ROLE_PATIENT" -> navigateToRoute(Screens.Patience.route, Screens.Splash.SplashScreen.route) + else -> navigateToRoute(Screens.Register.Login.route, Screens.Splash.SplashScreen.route) } } - fun navigateToDoctor() { + fun navigateToRoute(destination: String, current: String) { postEffect( SplashContract.Effect.NavigateTo( - destination = Screens.Doctor.DoctorMain.route, + destination = destination, navOptions = navOptions { - popUpTo(Screens.Splash.SplashScreen.route) { + popUpTo(current) { inclusive = true } } )) } - fun navigateToCenter() { - postEffect( - SplashContract.Effect.NavigateTo( - destination = Screens.Center.CenterMain.route, - navOptions = navOptions { - popUpTo(Screens.Splash.SplashScreen.route) { - inclusive = true - } - } - )) - } - - fun navigateToPatience() { - postEffect( - SplashContract.Effect.NavigateTo( - destination = Screens.Patience.route, - navOptions = navOptions { - popUpTo(Screens.Splash.SplashScreen.route) { - inclusive = true - } - } - )) - } - - fun navigateToLogin() { - postEffect( - SplashContract.Effect.NavigateTo( - destination = Screens.Register.Login.route, - navOptions = navOptions { - popUpTo(Screens.Splash.SplashScreen.route) { - inclusive = true - } - } - )) - } } \ No newline at end of file From cc0dd72024b793a55dca4495dfb1e1d720279ad4 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Sun, 19 May 2024 12:48:34 +0900 Subject: [PATCH 02/19] =?UTF-8?q?[fix]=20http=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=9D=B4=EC=8A=88=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/deploymentTargetDropDown.xml | 17 +++++++++++++++++ app/src/main/AndroidManifest.xml | 5 +---- .../main/res/xml/network_security_config.xml | 8 ++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 app/src/main/res/xml/network_security_config.xml diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..53d9ee6 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d62d5c7..d76a0b2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,6 +15,7 @@ - - diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..f18e1f0 --- /dev/null +++ b/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file From 9493139d0b6bdea680fe75e3f63b0978f906fb03 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Sun, 19 May 2024 12:50:40 +0900 Subject: [PATCH 03/19] =?UTF-8?q?[fix]=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/screens/auth/login/LoginScreen.kt | 13 +++++- .../screens/auth/login/LoginViewModel.kt | 43 ++++++++++++------- app/src/main/res/values/strings.xml | 2 +- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginScreen.kt b/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginScreen.kt index 5c411a4..6b5708c 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginScreen.kt @@ -77,7 +77,7 @@ fun LoginScreen( modifier = Modifier .align(Alignment.TopStart) .padding(start = 22.dp, top = 117.dp), - text = stringResource(id = R.string.스스로를_돌아볼_수_있는), + text = stringResource(id = R.string.여러분_곁을_따뜻하게_지켜드릴게요), style = RemindTheme.typography.onBoardingFont.copy(color = RemindTheme.colors.white) ) Image( @@ -105,4 +105,15 @@ fun LoginScreen( } } } +} + +@Preview(showBackground = false) +@Composable +fun LoginPreview() { + Text( + modifier = Modifier + .padding(start = 22.dp, top = 117.dp), + text = stringResource(id = R.string.여러분_곁을_따뜻하게_지켜드릴게요), + style = RemindTheme.typography.onBoardingFont.copy(color = RemindTheme.colors.white) + ) } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginViewModel.kt index 309ad59..a19500f 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/login/LoginViewModel.kt @@ -10,6 +10,7 @@ import com.example.remind.data.model.request.KakaoLoginRequest import com.example.remind.data.network.adapter.ApiResult import com.example.remind.data.network.interceptor.TokenManager import com.example.remind.domain.usecase.onboarding_usecase.KakaoTokenUseCase +import com.example.remind.feature.screens.auth.splash.SplashContract import com.kakao.sdk.auth.model.OAuthToken import com.kakao.sdk.common.model.ClientError import com.kakao.sdk.common.model.ClientErrorCause @@ -44,7 +45,6 @@ class LoginViewModel @Inject constructor( Log.e("kakao", "카카오 로그인 실패") } else if(token != null) { UserApiClient.instance.me { user, error -> - Timber.tag("kakao").e(token.accessToken + " && " + user) viewModelScope.launch { socialLogin(token.accessToken) } @@ -81,32 +81,45 @@ private fun socialLogin(token: String) { result.data.data.refreshToken ) tokenManager.saveUserName(result.data.data.name) + if(result.data.data.rolesType != "ROLE_UNREGISTER") { + tokenManager.saveUserType(result.data.data.rolesType) + } + } + when(result.data.data.rolesType) { + "ROLE_DOCTOR" -> navigateToRoute(Screens.Doctor.DoctorMain.route, Screens.Register.Login.route) + "ROLE_CENTER" -> navigateToRoute(Screens.Center.CenterMain.route, Screens.Register.Login.route) + "ROLE_PATIENT" -> navigateToRoute(Screens.Patience.route, Screens.Register.Login.route) + else -> navigateToRoute(Screens.Register.SelectType.route, Screens.Register.Login.route) } - postEffect( - LoginContract.Effect.NavigateTo( - destinaton = Screens.Register.SelectType.route, - navOptions = navOptions { - popUpTo( - Screens.Register.Login.route - ) - } - ) - ) - Timber.d("${tokenManager.getAccessToken()} ||| ${tokenManager.getRefreshToken()}") } is ApiResult.Failure.UnknownApiError -> { - postEffect(LoginContract.Effect.Toastmessage("리마인드 고객센터에 문의하세요")) + setToastMessage("리마인드 고객센터에 문의하세요") } is ApiResult.Failure.NetworkError -> { - postEffect(LoginContract.Effect.Toastmessage("네트워크 설정을 확인해주세요")) + setToastMessage("네트워크 설정을 확인해주세요") } is ApiResult.Failure.HttpError -> { - postEffect(LoginContract.Effect.Toastmessage("Http 오류가 발생했습니다")) + setToastMessage("api 응답에러 ${result.code}") } else -> {} } } } + fun navigateToRoute(destination: String, current: String) { + postEffect( + LoginContract.Effect.NavigateTo( + destinaton = destination, + navOptions = navOptions { + popUpTo(current) { + inclusive = true + } + } + ) + ) + } + fun setToastMessage(text: String) { + postEffect(LoginContract.Effect.Toastmessage(text)) + } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 20e00e3..5858ba3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,7 +7,7 @@ Next Previous - 스스로를 돌아볼 수 있는\n당신만의 공간으로 초대합니다. + 여러분 곁을\n따듯하게 지켜드릴게요! 카카오로 로그인하기 진료실 밖 일상을 더하다 환자용 From 4f29ff4652a225e15cacceb3783156ee6757eddc Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Sun, 19 May 2024 13:06:02 +0900 Subject: [PATCH 04/19] =?UTF-8?q?[fix]=20=ED=9A=8C=EC=9B=90=EC=9C=A0?= =?UTF-8?q?=ED=98=95=20=EC=84=A0=ED=83=9D=20ui=EB=B0=8F=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=A0=84=ED=99=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/onboarding/OnBoardingViewModel.kt | 40 +++++-------------- .../auth/onboarding/SelectTypeScreen.kt | 21 +++++----- app/src/main/res/values/strings.xml | 4 +- 3 files changed, 22 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt index d264604..4c9169d 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt @@ -40,12 +40,15 @@ class OnBoardingViewModel @Inject constructor( when(event) { is OnBoardingContract.Event.DoctorButtonClicked -> { updateState(currentState.copy("ROLE_DOCTOR")) + saveUserType("ROLE_DOCTOR") } is OnBoardingContract.Event.CenterButtonClicked -> { updateState(currentState.copy("ROLE_CENTER")) + saveUserType("ROLE_CENTER") } is OnBoardingContract.Event.PatienceButtonClicked -> { updateState(currentState.copy("ROLE_PATIENT")) + saveUserType("ROLE_PATIENT") } is OnBoardingContract.Event.NextButtonFinal -> { getFcmToken() @@ -56,12 +59,11 @@ class OnBoardingViewModel @Inject constructor( //navigateToRoute(event.destinationRoute, event.currentRoute) } is OnBoardingContract.Event.NextButtonClicked -> { - saveUserType(currentState.selectedType!!) navigateToNext(currentState.selectedType!!) } //의사부터 이걸로 통합시킴 is OnBoardingContract.Event.NavigateButtonClicked -> { - navigateToRoute(event.destinationRoute, event.currentRoute) + navigateToRoute(event.destinationRoute, event.currentRoute, false) } else ->{} } @@ -75,37 +77,13 @@ class OnBoardingViewModel @Inject constructor( fun navigateToNext(selectType: String) { if(selectType == "ROLE_DOCTOR") { - postEffect( - OnBoardingContract.Effect.NavigateTo( - destination = Screens.Register.OnBoardingCheckDoctor.route, - navOptions = navOptions { - popUpTo(Screens.Register.SelectType.route) { - inclusive = true - } - } - )) + navigateToRoute(Screens.Register.OnBoardingCheckDoctor.route, Screens.Register.SelectType.route, false) } if(selectType == "ROLE_PATIENT") { - postEffect( - OnBoardingContract.Effect.NavigateTo( - destination = Screens.Register.OnBoardingPatience.route, - navOptions = navOptions { - popUpTo(Screens.Register.SelectType.route) { - inclusive = true - } - } - )) + navigateToRoute(Screens.Register.OnBoardingPatience.route, Screens.Register.SelectType.route,false) } if(selectType == "ROLE_CENTER") { - postEffect( - OnBoardingContract.Effect.NavigateTo( - destination = Screens.Register.OnBoardingCenter.route, - navOptions = navOptions { - popUpTo(Screens.Register.SelectType.route) { - inclusive = true - } - } - )) + navigateToRoute(Screens.Register.OnBoardingCenter.route, Screens.Register.SelectType.route,false) } } fun navigateToFinal() { @@ -133,13 +111,13 @@ class OnBoardingViewModel @Inject constructor( //나중에 이걸로 통합 수정하기 - fun navigateToRoute(destinationRoute: String, currentRoute: String) { + fun navigateToRoute(destinationRoute: String, currentRoute: String, inclusiveData: Boolean) { postEffect( OnBoardingContract.Effect.NavigateTo( destination = destinationRoute, navOptions = navOptions { popUpTo(currentRoute) { - inclusive = true + inclusive = inclusiveData } } ) diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt index bc08bad..f1d9aff 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt @@ -65,19 +65,19 @@ fun SelectTypeScreen( BasicOnBoardingAppBar( modifier = Modifier.fillMaxWidth(), weight = 0.3f, - title = stringResource(id = R.string.환자_관리) + title = "" ) Text( - modifier = Modifier.padding(start = 20.dp, top = 31.dp), + modifier = Modifier.padding(start = 20.dp, top = 35.dp), textAlign = TextAlign.Start, - text = stringResource(id = R.string.사용_입장_선택), + text = stringResource(id = R.string.사용자_유형_선택), style = RemindTheme.typography.h1Bold.copy(color = RemindTheme.colors.text) ) Text( modifier = Modifier.padding(start = 20.dp, top = 12.dp), textAlign = TextAlign.Start, - text = stringResource(id = R.string.어떤_입장에서_사용하실지_선택해주세요), - style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.grayscale_3) + text = stringResource(id = R.string.서비스_이용을_위한_사용자_유형을_선택해주세요), + style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.grayscale_3, lineHeight = 22.sp) ) Spacer(modifier = Modifier.weight(1f)) Column( @@ -183,12 +183,13 @@ fun typeButton( } } -@Preview(showBackground = false) +@Preview(showBackground = true) @Composable fun SelectTypePreview() { - BasicOnBoardingAppBar( - //modifier = Modifier.fillMaxWidth(), - weight = 0.3f, - title = stringResource(id = R.string.환자_관리) + Text( + modifier = Modifier.padding(start = 20.dp, top = 12.dp), + textAlign = TextAlign.Start, + text = stringResource(id = R.string.서비스_이용을_위한_사용자_유형을_선택해주세요), + style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.grayscale_3, lineHeight = 22.sp) ) } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5858ba3..687db6e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -62,8 +62,8 @@ 오늘 하루 기분이 어떠셨나요? 당신의 하루가 궁금해요 오늘의 기분 기록하기 - 사용 입장 선택 - 어떤 입장에서 사용하실지 선택해주세요! + 사용자 유형 선택 + 서비스 이용을 위한\n사용자 유형을 선택해주세요! 김말랑 님, 좋은 하루 되세요! 관리 중인 환자 From ae3d1cdc4e4e2f3d34dd7f32c078eeac219e8067 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Sun, 19 May 2024 20:29:30 +0900 Subject: [PATCH 05/19] =?UTF-8?q?[fix]=20=EC=95=BD=20=EB=B3=B5=EC=9A=A9?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20api=20=EC=97=B0=EA=B2=B0=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/deploymentTargetDropDown.xml | 17 ---- .../core/common/component/MedicineItem.kt | 66 +++++++++----- .../core/common/component/RemindTextField.kt | 86 +++++++++++++++++++ .../example/remind/data/di/NetworkModule.kt | 6 ++ .../response/MedicingDailyInfoResponse.kt | 24 ++++++ .../data/network/interceptor/TokenManager.kt | 2 +- .../data/network/service/PatientService.kt | 8 ++ .../patient/PatientMedicineRepository.kt | 8 ++ .../patient/PatientMedicineRepositoryImpl.kt | 17 ++++ .../PatientMedicineDailyUseCase.kt | 14 +++ .../onboarding/OnBoardingLoadingDoctor.kt | 2 +- .../auth/onboarding/OnBoardingPatience.kt | 20 ++++- .../auth/onboarding/OnBoardingViewModel.kt | 36 ++------ .../screens/patience/home/HomeContract.kt | 9 +- .../patience/home/HomeMedicineDialog.kt | 13 +-- .../screens/patience/home/HomeScreen.kt | 58 ++++++++++++- .../screens/patience/home/HomeViewModel.kt | 62 ++++++++++++- app/src/main/res/values/strings.xml | 1 + 18 files changed, 361 insertions(+), 88 deletions(-) delete mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt create mode 100644 app/src/main/java/com/example/remind/data/model/response/MedicingDailyInfoResponse.kt create mode 100644 app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt create mode 100644 app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/PatientMedicineDailyUseCase.kt diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml deleted file mode 100644 index 53d9ee6..0000000 --- a/.idea/deploymentTargetDropDown.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt b/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt index fe22aea..965f4f0 100644 --- a/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt +++ b/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt @@ -7,6 +7,7 @@ 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.width @@ -31,6 +32,9 @@ fun MedicineItem( score: Float, doseClick: () -> Unit, unadministeredClick: () -> Unit, + isTaking: Boolean, + isTakingTime: String, + notTakingReason: String ) { Box( modifier = modifier @@ -63,33 +67,51 @@ fun MedicineItem( ) } Spacer(modifier = modifier.height(4.dp)) - Row() { - //시간이 정해져있을 경우 바꿔지도록 하기 - Text( - modifier = modifier - .weight(0.5f) - .background( - color = RemindTheme.colors.main_6, - shape = RoundedCornerShape(bottomStart = 12.dp) + if(isTaking == false) { + Row() { + //시간이 정해져있을 경우 바꿔지도록 하기 + Text( + modifier = modifier + .weight(0.5f) + .background( + color = RemindTheme.colors.main_6, + shape = RoundedCornerShape(bottomStart = 12.dp) + ) + .clickable { doseClick }, + text = stringResource(id = R.string.복용), + textAlign= TextAlign.Center, + style = RemindTheme.typography.c1Bold.copy( + color = RemindTheme.colors.white, + lineHeight = 20.sp ) - .clickable { doseClick }, - text = stringResource(id = R.string.복용), - textAlign= TextAlign.Center, - style = RemindTheme.typography.c1Bold.copy( - color = RemindTheme.colors.white, - lineHeight = 20.sp ) - ) - Spacer(modifier = modifier.width(2.dp)) + Spacer(modifier = modifier.width(2.dp)) + Text( + modifier = modifier + .fillMaxWidth() + .background( + color = RemindTheme.colors.main_5, + shape = RoundedCornerShape(bottomEnd = 12.dp) + ) + .clickable { unadministeredClick }, + text = stringResource(id = R.string.미복용), + textAlign= TextAlign.Center, + style = RemindTheme.typography.c1Bold.copy( + color = RemindTheme.colors.white, + lineHeight = 20.sp + ) + ) + } + } else { Text( modifier = modifier - .weight(0.5f) + .fillMaxWidth() .background( - color = RemindTheme.colors.main_5, - shape = RoundedCornerShape(bottomEnd = 12.dp) + color = RemindTheme.colors.slate_500, + shape = RoundedCornerShape(bottomStart = 12.dp) ) - .clickable { unadministeredClick }, - text = stringResource(id = R.string.미복용), + .clickable { doseClick }, + text = if(notTakingReason.isNotEmpty()) "미복용" else isTakingTime, textAlign= TextAlign.Center, style = RemindTheme.typography.c1Bold.copy( color = RemindTheme.colors.white, @@ -104,5 +126,5 @@ fun MedicineItem( @Preview @Composable fun ItemPreview() { - MedicineItem(time = "아침", score= 2.0f, doseClick = {}, unadministeredClick = {}) + MedicineItem(time = "아침", score= 2.0f, doseClick = {}, unadministeredClick = {}, isTaking = true, isTakingTime = "오전 7:00", notTakingReason = "미복용") } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt b/app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt new file mode 100644 index 0000000..1afbbb2 --- /dev/null +++ b/app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt @@ -0,0 +1,86 @@ +package com.example.remind.core.common.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsFocusedAsState +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.example.remind.core.designsystem.theme.RemindTheme + +@Composable +fun RemindTextField( + modifier: Modifier = Modifier, + onTextChanged: (String) -> Unit, + text: String, + roundedShape: Dp, + hintText: String, + verticalPadding: Dp, +) { + val interactionSource = remember { MutableInteractionSource() } + val isFocused = interactionSource.collectIsFocusedAsState() + val hintTextVisible by remember { + derivedStateOf { text.isEmpty() && !isFocused.value } + } + BasicTextField( + value = text, + maxLines = 1, + onValueChange = onTextChanged, + interactionSource = interactionSource, + textStyle = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.text), + modifier = modifier + .fillMaxWidth() + .background(color = RemindTheme.colors.slate_100, shape = RoundedCornerShape(roundedShape)) + .run { + if (isFocused.value) { + border( + width = 2.dp, + shape = RoundedCornerShape(roundedShape), + color = RemindTheme.colors.main_5 + ) + } else { + this + } + }, + decorationBox = { innerTextField -> + Box( + modifier = modifier + .fillMaxWidth() + .padding(top = verticalPadding, bottom = verticalPadding, start= 12.dp) + ) { + if(hintTextVisible) { + Text( + text = hintText, + style = RemindTheme.typography.c1Regular.copy(color = RemindTheme.colors.slate_400) + ) + } + innerTextField() + } + } + ) +} + +@Preview(showBackground = false) +@Composable +fun BasicTextFieldPreview() { + RemindTextField( + onTextChanged = {}, + text = "", + roundedShape = 8.dp, + hintText = "fjle", + verticalPadding = 13.dp, + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/di/NetworkModule.kt b/app/src/main/java/com/example/remind/data/di/NetworkModule.kt index ba54062..c6029ab 100644 --- a/app/src/main/java/com/example/remind/data/di/NetworkModule.kt +++ b/app/src/main/java/com/example/remind/data/di/NetworkModule.kt @@ -10,6 +10,8 @@ import com.example.remind.data.repository.auth.AuthRepository import com.example.remind.data.repository.auth.AuthRepositoryImpl import com.example.remind.data.repository.auth.TokenRepository import com.example.remind.data.repository.auth.TokenRepositoryImpl +import com.example.remind.data.repository.patient.PatientMedicineRepository +import com.example.remind.data.repository.patient.PatientMedicineRepositoryImpl import dagger.Binds import dagger.Module import dagger.Provides @@ -75,6 +77,10 @@ object NetworkModule { @Singleton @Binds abstract fun providesTokenRepository(tokenRepositoryImpl: TokenRepositoryImpl): TokenRepository + + @Singleton + @Binds + abstract fun providesPatientMedicineRepository(patientMedicineRepositoryImpl: PatientMedicineRepositoryImpl): PatientMedicineRepository } } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/MedicingDailyInfoResponse.kt b/app/src/main/java/com/example/remind/data/model/response/MedicingDailyInfoResponse.kt new file mode 100644 index 0000000..5f42c31 --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/MedicingDailyInfoResponse.kt @@ -0,0 +1,24 @@ +package com.example.remind.data.model.response + +import kotlinx.serialization.Serializable + +@Serializable +data class MedicingDailyInfoResponse( + val code: Int, + val `data`: MedicineData, + val message: String +) +@Serializable +data class MedicineData( + val dailyTakingMedicineDtos: List +) + +@Serializable +data class DailyTakingMedicineList( + val importance: Int, + val isTaking: Boolean, + val medicinesType: String, + val notTakingReason: String, + val prescriptionId: Int, + val takingTime: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/network/interceptor/TokenManager.kt b/app/src/main/java/com/example/remind/data/network/interceptor/TokenManager.kt index 3a52ca1..1734d6b 100644 --- a/app/src/main/java/com/example/remind/data/network/interceptor/TokenManager.kt +++ b/app/src/main/java/com/example/remind/data/network/interceptor/TokenManager.kt @@ -56,7 +56,7 @@ class TokenManager @Inject constructor( suspend fun saveUserId(userId: Int) { datastore.edit { prefs -> - prefs[USER_ID] + prefs[USER_ID] = userId } } diff --git a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt index 42b33ce..790ac14 100644 --- a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt +++ b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt @@ -1,9 +1,11 @@ package com.example.remind.data.network.service import com.example.remind.data.model.response.MedicineInfoResponse +import com.example.remind.data.model.response.MedicingDailyInfoResponse import com.example.remind.data.network.adapter.ApiResult import retrofit2.http.GET import retrofit2.http.Path +import retrofit2.http.Query interface PatientService { @GET("/taking-medicine") @@ -11,4 +13,10 @@ interface PatientService { @Path("memberId") memberId:Int, @Path("date") string:Int, ): ApiResult + + @GET("/taking-medicine/daily") + suspend fun getMedicineDailyInfo( + @Query("memberId") memberId:Int, + @Query("date") string:String, + ): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt new file mode 100644 index 0000000..0950962 --- /dev/null +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt @@ -0,0 +1,8 @@ +package com.example.remind.data.repository.patient + +import com.example.remind.data.model.response.MedicingDailyInfoResponse +import com.example.remind.data.network.adapter.ApiResult + +interface PatientMedicineRepository { + suspend fun getMedicineDaily(memberId: Int, date:String): ApiResult +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt new file mode 100644 index 0000000..4f85550 --- /dev/null +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt @@ -0,0 +1,17 @@ +package com.example.remind.data.repository.patient + +import com.example.remind.data.model.response.MedicingDailyInfoResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.network.service.PatientService +import javax.inject.Inject + +class PatientMedicineRepositoryImpl @Inject constructor( + private val service: PatientService +): PatientMedicineRepository { + override suspend fun getMedicineDaily( + memberId: Int, + date: String + ): ApiResult { + return service.getMedicineDailyInfo(memberId, date) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/PatientMedicineDailyUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/PatientMedicineDailyUseCase.kt new file mode 100644 index 0000000..8205080 --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/PatientMedicineDailyUseCase.kt @@ -0,0 +1,14 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.response.MedicingDailyInfoResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMedicineRepository +import javax.inject.Inject + +class PatientMedicineDailyUseCase @Inject constructor( + private val patientMedicineRepository: PatientMedicineRepository +) { + suspend operator fun invoke(memberId: Int, date: String): ApiResult { + return patientMedicineRepository.getMedicineDaily(memberId, date) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingLoadingDoctor.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingLoadingDoctor.kt index 6f76308..5b2025a 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingLoadingDoctor.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingLoadingDoctor.kt @@ -31,7 +31,7 @@ fun OnBoardingLoadingDoctorScreen(navController: NavHostController) { val effectFlow = viewModel.effect LaunchedEffect(true) { delay(3000) - viewModel.navigateToFinal() + //viewModel.navigateToFinal() effectFlow.collectLatest { effect-> when(effect) { is OnBoardingContract.Effect.NavigateTo -> { diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt index 6718cea..49de315 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt @@ -38,6 +38,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController import com.example.remind.R import com.example.remind.core.common.component.BasicOnBoardingAppBar +import com.example.remind.core.common.component.RemindTextField import com.example.remind.core.designsystem.theme.Pretendard import com.example.remind.core.designsystem.theme.RemindTheme import com.example.remind.data.model.request.OnBoardingRequest @@ -52,6 +53,13 @@ fun OnBoardingPatienceScreen( val context = LocalContext.current var isChecked by remember{ mutableStateOf(false) } + val textState = remember { mutableStateOf("") } + val handleTextChange = { newText: String -> + textState.value = newText + } + + val textFieldModifier = Modifier.padding(16.dp) + LaunchedEffect(true) { effectFlow.collectLatest { effect -> when(effect) { @@ -99,13 +107,17 @@ fun OnBoardingPatienceScreen( ), ) Spacer(modifier = Modifier.height(56.dp)) - Image( + RemindTextField( modifier = Modifier .fillMaxWidth() .padding(start = 20.dp, end = 20.dp), - painter = painterResource(id = R.drawable.ic_example1), - contentDescription = null + onTextChanged = handleTextChange, + text = textState.value, + roundedShape = 8.dp, + hintText = stringResource(id = R.string.번호를_입력해주세요), + verticalPadding = 12.dp ) + Spacer(modifier = Modifier.height(12.dp)) CheckReading( modifier = Modifier.fillMaxWidth(), @@ -125,7 +137,7 @@ fun OnBoardingPatienceScreen( centerName = "", city = "", district = "", - protectorPhoneNumber = "01088644622", + protectorPhoneNumber = textState.value, rolesType = "ROLE_PATIENT", fcmToken = "" ) diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt index 4c9169d..a398e77 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt @@ -51,9 +51,15 @@ class OnBoardingViewModel @Inject constructor( saveUserType("ROLE_PATIENT") } is OnBoardingContract.Event.NextButtonFinal -> { - getFcmToken() - postOnBoarding(event.onBoardingData.copy(fcmToken = currentState.fcmToken)) - if(currentState.moveAble == true) navigateToFinal() +// getFcmToken() +// postOnBoarding(event.onBoardingData.copy(fcmToken = currentState.fcmToken)) + if(currentState.selectedType == "ROLE_PATIENT") { + navigateToRoute(Screens.Register.OnBoardingFinal.route, Screens.Register.OnBoardingPatience.route, true) + getFcmToken() + postOnBoarding(event.onBoardingData.copy(fcmToken = currentState.fcmToken)) + } else if(currentState.selectedType == "ROLE_CENTER") { + navigateToRoute(Screens.Register.OnBoardingFinal.route, Screens.Register.OnBoardingCenter.route, true) + } } is OnBoardingContract.Event.NextButtonToPatience -> { //navigateToRoute(event.destinationRoute, event.currentRoute) @@ -86,31 +92,7 @@ class OnBoardingViewModel @Inject constructor( navigateToRoute(Screens.Register.OnBoardingCenter.route, Screens.Register.SelectType.route,false) } } - fun navigateToFinal() { - postEffect( - OnBoardingContract.Effect.NavigateTo( - destination = Screens.Register.OnBoardingFinal.route, - navOptions = navOptions { - popUpTo(Screens.Register.OnBoardingPatience.route) { - inclusive = true - } - } - )) - } -// fun navigateToPatience() { -// postEffect( -// OnBoardingContract.Effect.NavigateTo( -// destination = Screens.Patience.route, -// navOptions = navOptions { -// popUpTo(Screens.Register.OnBoardingFinal.route) { -// inclusive = true -// } -// } -// )) -// } - - //나중에 이걸로 통합 수정하기 fun navigateToRoute(destinationRoute: String, currentRoute: String, inclusiveData: Boolean) { postEffect( OnBoardingContract.Effect.NavigateTo( diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt index 60975cc..851ac0b 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt @@ -6,16 +6,23 @@ import androidx.navigation.NavOptionsBuilder import com.example.remind.core.base.UiEffect import com.example.remind.core.base.UiEvent import com.example.remind.core.base.UiState +import com.example.remind.data.model.response.DailyTakingMedicineList +import com.example.remind.data.model.response.MedicineData class HomeContract { data class State( - val sosDialogState: Boolean = false + val sosDialogState: Boolean = false, + val medicineDialogState:Boolean = false, + val memberId:Int? = null, + val medicineDailyData: List = emptyList() ): UiState sealed class Event: UiEvent { data class WritingButtonClicked(val context: Context): Event() object showSosDialog: Event() object DismissDialog: Event() + object showMediDialog: Event() + object dismissMediDialog: Event() data class CallButtonClicked(val context: Context, val number: String):Event() } sealed class Effect: UiEffect { diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt index 5ac3986..70b7b53 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt @@ -6,17 +6,13 @@ 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.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.RoundedCornerShape import androidx.compose.material.Icon -import androidx.compose.material.IconButton import androidx.compose.material.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -36,9 +32,6 @@ fun HomeMedicineDialog ( onDismissClick: () -> Unit, onConfirmClick: () -> Unit, selectReason: () -> Unit, - selectBackground: Color, - confirmBackground: Color, - confirmTextColor: Color, showDialog:Boolean, ) { BasicDialog( @@ -47,9 +40,9 @@ fun HomeMedicineDialog ( onDismissClick = onDismissClick, onConfirmClick = onConfirmClick, selectReason = selectReason, - selectBackground = selectBackground, - confirmBackground = confirmBackground, - confirmTextColor = confirmTextColor + selectBackground = RemindTheme.colors.main_5, + confirmBackground = RemindTheme.colors.main_5, + confirmTextColor = RemindTheme.colors.white ) }, showDialog = showDialog diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt index 4c0788f..887cbb6 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt @@ -25,6 +25,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape @@ -55,11 +56,13 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController import com.example.remind.R import com.example.remind.core.common.component.BasicButton +import com.example.remind.core.common.component.MedicineItem import com.example.remind.core.designsystem.theme.RemindTheme import com.example.remind.data.model.CalendarUiModel import com.example.remind.data.repository.CalendarDataSource import kotlinx.coroutines.flow.collectLatest import java.time.LocalDate +import java.time.format.DateTimeFormatter @RequiresApi(Build.VERSION_CODES.O) @Composable @@ -68,6 +71,7 @@ fun HomeScreen(navController: NavHostController) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() val effectFlow = viewModel.effect val context = LocalContext.current + var selectDate: Int = 0 val requestPermissionLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.RequestPermission(), onResult = { isGranted: Boolean -> @@ -78,7 +82,9 @@ fun HomeScreen(navController: NavHostController) { } } ) - + var year = LocalDate.now().year + var month = LocalDate.now().monthValue + var day = LocalDate.now().dayOfMonth val dataSource = CalendarDataSource() var calendarUiModel by remember { mutableStateOf(dataSource.getData(lastSelectedDate = dataSource.today)) } val scrollState = rememberScrollState() @@ -97,7 +103,8 @@ fun HomeScreen(navController: NavHostController) { context.startActivity(intent) } } - else-> {} + else-> { + } } } } @@ -119,6 +126,15 @@ fun HomeScreen(navController: NavHostController) { ) } + if(uiState.medicineDialogState) { + HomeMedicineDialog( + onDismissClick = { viewModel.reduceState(HomeContract.Event.dismissMediDialog) }, + onConfirmClick = { /*TODO*/ }, + selectReason = { /*TODO*/ }, + showDialog = uiState.medicineDialogState + ) + } + RemindTheme { Column( modifier = Modifier @@ -133,6 +149,10 @@ fun HomeScreen(navController: NavHostController) { modifier = Modifier.fillMaxWidth(), data = calendarUiModel, onDateClicked = { date -> + selectDate = date.date.dayOfMonth + var selectYear = date.date.year + var selectMonth = date.date.format(DateTimeFormatter.ofPattern("MM")) + viewModel.getMedicineDaily(0, "${selectYear}-${selectMonth}-${selectDate}") calendarUiModel = calendarUiModel.copy( selectedDate = date, visibleDates = calendarUiModel.visibleDates.map { @@ -179,7 +199,35 @@ fun HomeScreen(navController: NavHostController) { style = RemindTheme.typography.b2Bold.copy(color = Color(0xFF1F2937)) ) Spacer(modifier = Modifier.height(10.dp)) - EmptyMedicineList() + if(uiState.medicineDailyData.isEmpty()) { + EmptyMedicineList() + } else { + LazyRow( + modifier = Modifier.fillMaxWidth() + ) { + itemsIndexed(uiState.medicineDailyData) {index, item -> + var timeText: String="" + if(item.medicinesType == "BREAKFAST"){ + timeText = "아침" + } else if(item.medicinesType == "LUNCH") { + timeText = "점심" + } else if(item.medicinesType == "DINNER") { + timeText = "저녁" + } + MedicineItem( + time = timeText, + score = item.importance.toFloat(), + doseClick = { + viewModel.setEvent(HomeContract.Event.showMediDialog) + }, + unadministeredClick = {}, + isTaking = item.isTaking, + isTakingTime = item.takingTime, + notTakingReason = item.notTakingReason + ) + } + } + } Spacer(modifier = Modifier.height(23.dp)) Text( text = stringResource(id = R.string.오늘_하루_기분이_어떠셨나요), @@ -378,6 +426,10 @@ fun EmptyMedicineList( } } +fun MedicineList() { + +} + @Composable fun EmptyTodayMoodContainer( modifier: Modifier = Modifier, diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt index 5213bb6..a0a7cb1 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt @@ -1,14 +1,35 @@ package com.example.remind.feature.screens.patience.home import android.content.Context +import androidx.lifecycle.viewModelScope import androidx.navigation.navOptions import com.example.remind.app.Screens import com.example.remind.core.base.BaseViewModel +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.network.interceptor.TokenManager +import com.example.remind.domain.usecase.patience_usecase.PatientMedicineDailyUseCase +import com.example.remind.feature.screens.auth.login.LoginContract +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch import javax.inject.Inject - -class HomeViewModel @Inject constructor(): BaseViewModel( +@HiltViewModel +class HomeViewModel @Inject constructor( + private val tokenManager: TokenManager, + private val patientMedicineDailyUseCase: PatientMedicineDailyUseCase +): BaseViewModel( initialState = HomeContract.State() ) { + init { + viewModelScope.launch { + val memberId = tokenManager.getUserId().first() + updateState( + currentState.copy( + memberId = memberId + ) + ) + } + } override fun reduceState(event: HomeContract.Event) { when(event) { is HomeContract.Event.WritingButtonClicked -> { @@ -20,12 +41,20 @@ class HomeViewModel @Inject constructor(): BaseViewModel { updateState(currentState.copy(sosDialogState = false)) } + is HomeContract.Event.showMediDialog -> { + updateState(currentState.copy(medicineDialogState = true)) + } + is HomeContract.Event.dismissMediDialog -> { + updateState(currentState.copy(medicineDialogState = false)) + } is HomeContract.Event.CallButtonClicked -> { setSosCall(event.context, event.number) } } } + + fun navigateToWriting() { postEffect( HomeContract.Effect.NavigateTo( @@ -39,9 +68,38 @@ class HomeViewModel @Inject constructor(): BaseViewModel { + val dailyTakingMedicineDtos = result.data?.data?.dailyTakingMedicineDtos ?: emptyList() + updateState(currentState.copy(medicineDailyData = dailyTakingMedicineDtos)) + } + is ApiResult.Failure.UnknownApiError -> { + setToastMessage("리마인드 고객센터에 문의하세요") + } + is ApiResult.Failure.NetworkError -> { + setToastMessage("네트워크 설정을 확인해주세요") + } + is ApiResult.Failure.HttpError -> { + setToastMessage("api 응답에러 ${result.code}") + } + } + } + } + + fun setToastMessage(text: String) { + postEffect(HomeContract.Effect.Toastmessage(text)) + } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 687db6e..2ed5b09 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -71,6 +71,7 @@ 삭제 추가하기 환자 관리 + 번호를 입력해주세요. 삭제하기 환자 추가하기 From b5313c693055a24347d60f766e2cf4af25f47854 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Sun, 19 May 2024 21:30:03 +0900 Subject: [PATCH 06/19] =?UTF-8?q?[fix]=20=EC=95=BD=20=EB=AF=B8=EB=B3=B5?= =?UTF-8?q?=EC=9A=A9=20=EB=B3=B5=EC=9A=A9=EC=A0=95=EB=B3=B4=20=EB=B3=B4?= =?UTF-8?q?=EB=82=B4=EB=8A=94=20api=20=EC=97=B0=EB=8F=99=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/request/SetMedicineInfoRequest.kt | 11 ++ .../model/response/SetMedicineInfoResponse.kt | 12 ++ .../data/network/service/PatientService.kt | 9 ++ .../patient/PatientMedicineRepository.kt | 4 + .../patient/PatientMedicineRepositoryImpl.kt | 7 ++ .../SetMedicineInfoUseCase.kt | 15 +++ .../screens/patience/home/HomeContract.kt | 5 +- .../patience/home/HomeMedicineDialog.kt | 111 +++++++++--------- .../screens/patience/home/HomeScreen.kt | 11 +- .../screens/patience/home/HomeViewModel.kt | 41 ++++--- 10 files changed, 149 insertions(+), 77 deletions(-) create mode 100644 app/src/main/java/com/example/remind/data/model/request/SetMedicineInfoRequest.kt create mode 100644 app/src/main/java/com/example/remind/data/model/response/SetMedicineInfoResponse.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SetMedicineInfoUseCase.kt diff --git a/app/src/main/java/com/example/remind/data/model/request/SetMedicineInfoRequest.kt b/app/src/main/java/com/example/remind/data/model/request/SetMedicineInfoRequest.kt new file mode 100644 index 0000000..aaf5e1d --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/request/SetMedicineInfoRequest.kt @@ -0,0 +1,11 @@ +package com.example.remind.data.model.request + +import kotlinx.serialization.Serializable + +@Serializable +data class SetMedicineInfoRequest( + val date: String, + val isTaking: Boolean, + val medicinesType: String, + val notTakingReason: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/SetMedicineInfoResponse.kt b/app/src/main/java/com/example/remind/data/model/response/SetMedicineInfoResponse.kt new file mode 100644 index 0000000..583d9c1 --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/SetMedicineInfoResponse.kt @@ -0,0 +1,12 @@ +package com.example.remind.data.model.response + +data class SetMedicineInfoResponse( + val code: Int, + val `data`: MedicineInfo, + val message: String +) + +data class MedicineInfo( + val isTaking: Boolean, + val notTakingReason: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt index 790ac14..9587b90 100644 --- a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt +++ b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt @@ -1,9 +1,13 @@ package com.example.remind.data.network.service +import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.model.response.MedicineInfoResponse import com.example.remind.data.model.response.MedicingDailyInfoResponse +import com.example.remind.data.model.response.SetMedicineInfoResponse import com.example.remind.data.network.adapter.ApiResult +import retrofit2.http.Body import retrofit2.http.GET +import retrofit2.http.POST import retrofit2.http.Path import retrofit2.http.Query @@ -19,4 +23,9 @@ interface PatientService { @Query("memberId") memberId:Int, @Query("date") string:String, ): ApiResult + + @POST("//taking-medicine") + suspend fun setMedicineInfo( + @Body body: SetMedicineInfoRequest + ): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt index 0950962..04e5a58 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt @@ -1,8 +1,12 @@ package com.example.remind.data.repository.patient +import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.model.response.MedicingDailyInfoResponse +import com.example.remind.data.model.response.OnBoardingResponse +import com.example.remind.data.model.response.SetMedicineInfoResponse import com.example.remind.data.network.adapter.ApiResult interface PatientMedicineRepository { suspend fun getMedicineDaily(memberId: Int, date:String): ApiResult + suspend fun setMedicineInfo(body: SetMedicineInfoRequest): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt index 4f85550..c006889 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt @@ -1,6 +1,9 @@ package com.example.remind.data.repository.patient +import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.model.response.MedicingDailyInfoResponse +import com.example.remind.data.model.response.OnBoardingResponse +import com.example.remind.data.model.response.SetMedicineInfoResponse import com.example.remind.data.network.adapter.ApiResult import com.example.remind.data.network.service.PatientService import javax.inject.Inject @@ -14,4 +17,8 @@ class PatientMedicineRepositoryImpl @Inject constructor( ): ApiResult { return service.getMedicineDailyInfo(memberId, date) } + + override suspend fun setMedicineInfo(body: SetMedicineInfoRequest): ApiResult { + return service.setMedicineInfo(body) + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SetMedicineInfoUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SetMedicineInfoUseCase.kt new file mode 100644 index 0000000..f0b28d2 --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SetMedicineInfoUseCase.kt @@ -0,0 +1,15 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.request.SetMedicineInfoRequest +import com.example.remind.data.model.response.SetMedicineInfoResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMedicineRepository +import javax.inject.Inject + +class SetMedicineInfoUseCase @Inject constructor( + private val patientMedicineRepository: PatientMedicineRepository +) { + suspend operator fun invoke(body: SetMedicineInfoRequest): ApiResult { + return patientMedicineRepository.setMedicineInfo((body)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt index 851ac0b..c42a385 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt @@ -13,8 +13,8 @@ class HomeContract { data class State( val sosDialogState: Boolean = false, val medicineDialogState:Boolean = false, - val memberId:Int? = null, - val medicineDailyData: List = emptyList() + val medicineDailyData: List = emptyList(), + val notTakingReason: String? = null ): UiState sealed class Event: UiEvent { @@ -24,6 +24,7 @@ class HomeContract { object showMediDialog: Event() object dismissMediDialog: Event() data class CallButtonClicked(val context: Context, val number: String):Event() + data class SendNotTakingReason(val medicineTime: String,val date: String, val notTakingReason: String):Event() } sealed class Effect: UiEffect { data class NavigateTo( diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt index 70b7b53..ee4a603 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Icon import androidx.compose.material.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.graphics.Color @@ -21,6 +22,8 @@ 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 androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.example.remind.R import com.example.remind.core.common.component.BasicButton import com.example.remind.core.common.component.BasicDialog @@ -31,19 +34,13 @@ fun HomeMedicineDialog ( modifier: Modifier = Modifier, onDismissClick: () -> Unit, onConfirmClick: () -> Unit, - selectReason: () -> Unit, showDialog:Boolean, ) { BasicDialog( popupContent = { - Content( + ContentMedicineDialog( onDismissClick = onDismissClick, - onConfirmClick = onConfirmClick, - selectReason = selectReason, - selectBackground = RemindTheme.colors.main_5, - confirmBackground = RemindTheme.colors.main_5, - confirmTextColor = RemindTheme.colors.white - ) + onConfirmClick = onConfirmClick) }, showDialog = showDialog ) @@ -51,15 +48,13 @@ fun HomeMedicineDialog ( @Composable -fun Content( +fun ContentMedicineDialog( modifier: Modifier = Modifier, onDismissClick: () -> Unit, onConfirmClick: () -> Unit, - selectReason: () -> Unit, - selectBackground: Color, - confirmBackground: Color, - confirmTextColor: Color ) { + val viewModel: HomeViewModel = hiltViewModel() + val uiState by viewModel.uiState.collectAsStateWithLifecycle() val reasonList = listOf( stringResource(id = R.string.까먹었어요), stringResource(id = R.string.스케줄_관리를_해야해요), @@ -99,23 +94,49 @@ fun Content( ) { Row { for(i in 0..1) { - ReasonButton( - modifier = Modifier.weight(1f), - text = reasonList.get(i), - background = selectBackground, - onClick = selectReason - ) + Box( + modifier = modifier + .background( + color = if (uiState.notTakingReason != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + shape = RoundedCornerShape(20.dp) + ) + .padding(end = 3.dp) + .clickable( + onClick = { uiState.copy(notTakingReason = reasonList.get(i)) } + ) + ) { + Text( + modifier = Modifier + .align(Alignment.Center) + .padding(vertical = 7.dp), + text = reasonList.get(i), + style = RemindTheme.typography.c1Medium.copy(color = RemindTheme.colors.slate_700) + ) + } } } Spacer(modifier = Modifier.height(6.dp)) Row { for(i in 2..3) { - ReasonButton( - modifier = Modifier.weight(1f), - text = reasonList.get(i), - background = selectBackground, - onClick = selectReason - ) + Box( + modifier = modifier + .background( + color = if (uiState.notTakingReason != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + shape = RoundedCornerShape(20.dp) + ) + .padding(end = 3.dp) + .clickable( + onClick = { uiState.copy(notTakingReason = reasonList.get(i)) } + ) + ) { + Text( + modifier = Modifier + .align(Alignment.Center) + .padding(vertical = 7.dp), + text = reasonList.get(i), + style = RemindTheme.typography.c1Medium.copy(color = RemindTheme.colors.slate_700) + ) + } } } BasicButton( @@ -124,8 +145,8 @@ fun Content( .padding(top = 22.dp, bottom = 16.dp), text = stringResource(id = R.string.완료), RoundedCorner = 12.dp, - backgroundColor = confirmBackground, - textColor = confirmTextColor, + backgroundColor = if(uiState.notTakingReason != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + textColor = if(uiState.notTakingReason != null) RemindTheme.colors.white else RemindTheme.colors.slate_300, verticalPadding = 13.dp, onClick = onConfirmClick, textStyle = RemindTheme.typography.b2Bold @@ -135,40 +156,16 @@ fun Content( } } -@Composable -fun ReasonButton ( - modifier: Modifier = Modifier, - text: String, - onClick: () -> Unit, - background: Color -) { - Box( - modifier = modifier - .background(color = background, shape = RoundedCornerShape(20.dp)) - .padding(end = 3.dp) - .clickable( - onClick = onClick - ) - ) { - Text( - modifier = Modifier - .align(Alignment.Center) - .padding(vertical = 7.dp), - text = text, - style = RemindTheme.typography.c1Medium.copy(color = RemindTheme.colors.slate_700) - ) - } + +fun saveText(text: String): String { + var selectText = text + return selectText } @Preview(showBackground = false) @Composable fun DialogPreview() { - Content( + ContentMedicineDialog( onDismissClick = { }, - onConfirmClick = { }, - selectReason = { }, - selectBackground = RemindTheme.colors.slate_100, - confirmBackground = RemindTheme.colors.slate_100, - confirmTextColor = RemindTheme.colors.slate_300 - ) + onConfirmClick = {}) } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt index 887cbb6..9251417 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt @@ -85,6 +85,8 @@ fun HomeScreen(navController: NavHostController) { var year = LocalDate.now().year var month = LocalDate.now().monthValue var day = LocalDate.now().dayOfMonth + var sendDate: String = "" + var medicineTime: String = "" val dataSource = CalendarDataSource() var calendarUiModel by remember { mutableStateOf(dataSource.getData(lastSelectedDate = dataSource.today)) } val scrollState = rememberScrollState() @@ -129,8 +131,9 @@ fun HomeScreen(navController: NavHostController) { if(uiState.medicineDialogState) { HomeMedicineDialog( onDismissClick = { viewModel.reduceState(HomeContract.Event.dismissMediDialog) }, - onConfirmClick = { /*TODO*/ }, - selectReason = { /*TODO*/ }, + onConfirmClick = { + viewModel.setEvent(HomeContract.Event.SendNotTakingReason(medicineTime, sendDate, uiState.notTakingReason!!)) + }, showDialog = uiState.medicineDialogState ) } @@ -152,6 +155,7 @@ fun HomeScreen(navController: NavHostController) { selectDate = date.date.dayOfMonth var selectYear = date.date.year var selectMonth = date.date.format(DateTimeFormatter.ofPattern("MM")) + sendDate = "${selectYear}-${selectMonth}-${selectDate}" viewModel.getMedicineDaily(0, "${selectYear}-${selectMonth}-${selectDate}") calendarUiModel = calendarUiModel.copy( selectedDate = date, @@ -209,10 +213,13 @@ fun HomeScreen(navController: NavHostController) { var timeText: String="" if(item.medicinesType == "BREAKFAST"){ timeText = "아침" + medicineTime = timeText } else if(item.medicinesType == "LUNCH") { timeText = "점심" + medicineTime = timeText } else if(item.medicinesType == "DINNER") { timeText = "저녁" + medicineTime = timeText } MedicineItem( time = timeText, diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt index a0a7cb1..de161b5 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt @@ -1,13 +1,16 @@ package com.example.remind.feature.screens.patience.home import android.content.Context +import android.util.Log import androidx.lifecycle.viewModelScope import androidx.navigation.navOptions import com.example.remind.app.Screens import com.example.remind.core.base.BaseViewModel +import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.network.adapter.ApiResult import com.example.remind.data.network.interceptor.TokenManager import com.example.remind.domain.usecase.patience_usecase.PatientMedicineDailyUseCase +import com.example.remind.domain.usecase.patience_usecase.SetMedicineInfoUseCase import com.example.remind.feature.screens.auth.login.LoginContract import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.first @@ -16,20 +19,11 @@ import javax.inject.Inject @HiltViewModel class HomeViewModel @Inject constructor( private val tokenManager: TokenManager, - private val patientMedicineDailyUseCase: PatientMedicineDailyUseCase + private val patientMedicineDailyUseCase: PatientMedicineDailyUseCase, + private val setMedicineInfoUseCase: SetMedicineInfoUseCase ): BaseViewModel( initialState = HomeContract.State() ) { - init { - viewModelScope.launch { - val memberId = tokenManager.getUserId().first() - updateState( - currentState.copy( - memberId = memberId - ) - ) - } - } override fun reduceState(event: HomeContract.Event) { when(event) { is HomeContract.Event.WritingButtonClicked -> { @@ -50,6 +44,9 @@ class HomeViewModel @Inject constructor( is HomeContract.Event.CallButtonClicked -> { setSosCall(event.context, event.number) } + is HomeContract.Event.SendNotTakingReason -> { + sendNotTakingReason(event.medicineTime, event.date, event.notTakingReason) + } } } @@ -67,11 +64,6 @@ class HomeViewModel @Inject constructor( ) ) } - - fun getUserId() { - tokenManager.getUserId() - } - fun setSosCall( context: Context, number:String) { postEffect( HomeContract.Effect.getCall(context, number) @@ -99,6 +91,23 @@ class HomeViewModel @Inject constructor( } } + fun sendNotTakingReason(medicineTime: String, date: String, notTakingReason: String) { + viewModelScope.launch { + val result = setMedicineInfoUseCase.invoke(SetMedicineInfoRequest( + date = date, + isTaking = false, + medicinesType = medicineTime, + notTakingReason = notTakingReason + )) + when(result) { + is ApiResult.Success -> { + Log.d("HomeViewModel", "success") + } + else -> {} + } + } + } + fun setToastMessage(text: String) { postEffect(HomeContract.Effect.Toastmessage(text)) } From 96402712785cf60bcdc4cf2b6f4f559f7af4c116 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Mon, 20 May 2024 21:04:03 +0900 Subject: [PATCH 07/19] =?UTF-8?q?[feat]=20=EA=B8=80=EC=9E=91=EC=84=B1=20ap?= =?UTF-8?q?i=20=EC=97=B0=EA=B2=B0=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/remind/app/RemindNavHost.kt | 5 +- .../java/com/example/remind/app/Screens.kt | 3 + .../core/common/component/IconContainer.kt | 58 ++++ .../core/common/component/MedicineItem.kt | 3 +- .../core/common/component/RemindTextField.kt | 13 +- .../remind/data/model/FeelingScoreModel.kt | 3 +- .../data/model/request/OnBoardingRequest.kt | 3 +- .../data/model/request/WritingMoodRequest.kt | 13 + .../model/response/ActivityListResponse.kt | 17 ++ .../response/MedicingDailyInfoResponse.kt | 7 +- .../data/model/response/MoodChartResponse.kt | 17 ++ .../model/response/WritingMoodResponse.kt | 10 + .../data/network/service/PatientService.kt | 22 +- .../patient/PatientMedicineRepository.kt | 7 + .../patient/PatientMedicineRepositoryImpl.kt | 21 ++ .../patience_usecase/GetActivityUseCase.kt | 14 + .../patience_usecase/GetMoodChartUseCase.kt | 19 ++ .../patience_usecase/SetTodayMoodUseCase.kt | 15 + .../remind/feature/screens/auth/AuthGraph.kt | 13 +- .../auth/onboarding/OnBoardingCheckDoctor.kt | 3 +- .../auth/onboarding/OnBoardingFinal.kt | 4 +- .../auth/onboarding/OnBoardingPatience.kt | 14 +- .../auth/onboarding/OnBoardingViewModel.kt | 20 +- .../auth/onboarding/SelectTypeScreen.kt | 6 +- .../feature/screens/patience/PatienceGraph.kt | 26 +- .../patience/home/HomeCheeringScreen.kt | 21 +- .../screens/patience/home/HomeContract.kt | 1 - .../screens/patience/home/HomeScreen.kt | 34 +-- .../screens/patience/home/HomeViewModel.kt | 27 +- .../screens/patience/medicine/AlarmDialog.kt | 209 +++++++++++++ .../patience/{ => medicine}/MedicineScreen.kt | 2 +- .../screens/patience/medicine/TimePicker.kt | 55 ++++ .../patience/writing/WritingContract.kt | 20 +- .../writing/WritingMoodStep1Screen.kt | 75 +---- .../writing/WritingMoodStep2FeelingScreen.kt | 184 ++++++++++++ .../writing/WritingMoodStep2LastScreen.kt | 281 ++++++++++++++++++ .../writing/WritingMoodStep2Screen.kt | 209 ++++++++++++- .../writing/WritingMoodStep3Screen.kt | 143 ++++++++- .../patience/writing/WritingViewModel.kt | 111 +++++-- app/src/main/res/drawable/ic_plus.xml | 16 + app/src/main/res/values/strings.xml | 11 +- 41 files changed, 1563 insertions(+), 172 deletions(-) create mode 100644 app/src/main/java/com/example/remind/core/common/component/IconContainer.kt create mode 100644 app/src/main/java/com/example/remind/data/model/request/WritingMoodRequest.kt create mode 100644 app/src/main/java/com/example/remind/data/model/response/ActivityListResponse.kt create mode 100644 app/src/main/java/com/example/remind/data/model/response/MoodChartResponse.kt create mode 100644 app/src/main/java/com/example/remind/data/model/response/WritingMoodResponse.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetActivityUseCase.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMoodChartUseCase.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SetTodayMoodUseCase.kt create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmDialog.kt rename app/src/main/java/com/example/remind/feature/screens/patience/{ => medicine}/MedicineScreen.kt (97%) create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/medicine/TimePicker.kt create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt create mode 100644 app/src/main/res/drawable/ic_plus.xml diff --git a/app/src/main/java/com/example/remind/app/RemindNavHost.kt b/app/src/main/java/com/example/remind/app/RemindNavHost.kt index b0dfbed..abfe1c5 100644 --- a/app/src/main/java/com/example/remind/app/RemindNavHost.kt +++ b/app/src/main/java/com/example/remind/app/RemindNavHost.kt @@ -1,6 +1,7 @@ package com.example.remind.app import androidx.compose.runtime.Composable +import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController @@ -8,17 +9,19 @@ import com.example.remind.feature.screens.center.CenterGraph import com.example.remind.feature.screens.doctor.DoctorGraph import com.example.remind.feature.screens.patience.PatienceScreen import com.example.remind.feature.screens.auth.RegisterGraph +import com.example.remind.feature.screens.auth.onboarding.OnBoardingViewModel import com.example.remind.feature.screens.auth.splash.SplashGraph @Composable fun RemindNavHost() { val navHostController = rememberNavController() + val onBoardingViewModel: OnBoardingViewModel = hiltViewModel() NavHost( navController = navHostController, startDestination = Screens.Splash.route ) { SplashGraph(navHostController) - RegisterGraph(navHostController) + RegisterGraph(navHostController, onBoardingViewModel) composable(route = Screens.Patience.route) { PatienceScreen() } diff --git a/app/src/main/java/com/example/remind/app/Screens.kt b/app/src/main/java/com/example/remind/app/Screens.kt index 458d19f..6191f9c 100644 --- a/app/src/main/java/com/example/remind/app/Screens.kt +++ b/app/src/main/java/com/example/remind/app/Screens.kt @@ -26,7 +26,10 @@ sealed class Screens(val route: String) { object Home: Screens("HomeScreen") { object WritingMoodStep1: Screens("writing_step1") object WritingMoodStep2: Screens("writing_step2") + object WritingMoodStep2Feeling: Screens("writing_step2_1") + object WritingMoodStep2Last: Screens("writing_step2_2") object WritingMoodStep3: Screens("writing_step3") + object SplashCheering: Screens("cheering") } object MoodChart: Screens("MoodChart") object Medicine: Screens("Medicine") diff --git a/app/src/main/java/com/example/remind/core/common/component/IconContainer.kt b/app/src/main/java/com/example/remind/core/common/component/IconContainer.kt new file mode 100644 index 0000000..b644a44 --- /dev/null +++ b/app/src/main/java/com/example/remind/core/common/component/IconContainer.kt @@ -0,0 +1,58 @@ +package com.example.remind.core.common.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.example.remind.core.designsystem.theme.RemindTheme +import com.example.remind.data.model.FeelingScoreModel + +@Composable +fun IconContainer( + modifier: Modifier = Modifier, + feelingScoreModel: FeelingScoreModel, + backgroundColor: Color, + onClick: () -> Unit +) { + Box( + modifier = modifier + .background(color = backgroundColor, shape = RoundedCornerShape(16.dp)) + .clickable(onClick = onClick) + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + modifier = modifier + .padding( + top = 18.dp, + start = 15.dp, + end = 15.dp, + bottom = 16.dp + ) + .size( + width = 25.dp, + height = 25.dp + ), + painter = painterResource(id = feelingScoreModel.imgeRes), + contentDescription = null + ) + Text( + modifier = modifier.padding(bottom = 15.dp), + text = feelingScoreModel.feeling, + style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.slate_700) + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt b/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt index 965f4f0..0180c63 100644 --- a/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt +++ b/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt @@ -69,7 +69,6 @@ fun MedicineItem( Spacer(modifier = modifier.height(4.dp)) if(isTaking == false) { Row() { - //시간이 정해져있을 경우 바꿔지도록 하기 Text( modifier = modifier .weight(0.5f) @@ -111,7 +110,7 @@ fun MedicineItem( shape = RoundedCornerShape(bottomStart = 12.dp) ) .clickable { doseClick }, - text = if(notTakingReason.isNotEmpty()) "미복용" else isTakingTime, + text = if(notTakingReason != "") "미복용" else isTakingTime, textAlign= TextAlign.Center, style = RemindTheme.typography.c1Bold.copy( color = RemindTheme.colors.white, diff --git a/app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt b/app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt index 1afbbb2..d16e7c0 100644 --- a/app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt +++ b/app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt @@ -28,7 +28,8 @@ fun RemindTextField( text: String, roundedShape: Dp, hintText: String, - verticalPadding: Dp, + topPadding: Dp, + bottomPadding: Dp ) { val interactionSource = remember { MutableInteractionSource() } val isFocused = interactionSource.collectIsFocusedAsState() @@ -59,7 +60,7 @@ fun RemindTextField( Box( modifier = modifier .fillMaxWidth() - .padding(top = verticalPadding, bottom = verticalPadding, start= 12.dp) + .padding(top = topPadding, bottom = bottomPadding, start= 12.dp) ) { if(hintTextVisible) { Text( @@ -76,11 +77,5 @@ fun RemindTextField( @Preview(showBackground = false) @Composable fun BasicTextFieldPreview() { - RemindTextField( - onTextChanged = {}, - text = "", - roundedShape = 8.dp, - hintText = "fjle", - verticalPadding = 13.dp, - ) + } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/FeelingScoreModel.kt b/app/src/main/java/com/example/remind/data/model/FeelingScoreModel.kt index 66048e3..70d5b00 100644 --- a/app/src/main/java/com/example/remind/data/model/FeelingScoreModel.kt +++ b/app/src/main/java/com/example/remind/data/model/FeelingScoreModel.kt @@ -3,5 +3,6 @@ package com.example.remind.data.model data class FeelingScoreModel ( val imgeRes: Int, val feeling: String, - val text: String + val text: String, + val description: String? = null ) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/request/OnBoardingRequest.kt b/app/src/main/java/com/example/remind/data/model/request/OnBoardingRequest.kt index df1d99c..b401e78 100644 --- a/app/src/main/java/com/example/remind/data/model/request/OnBoardingRequest.kt +++ b/app/src/main/java/com/example/remind/data/model/request/OnBoardingRequest.kt @@ -9,5 +9,6 @@ data class OnBoardingRequest( val district: String, val protectorPhoneNumber: String, val rolesType: String, - val fcmToken: String + val fcmToken: String, + val doctorLicenseNumber: String ) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/request/WritingMoodRequest.kt b/app/src/main/java/com/example/remind/data/model/request/WritingMoodRequest.kt new file mode 100644 index 0000000..ddd1d63 --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/request/WritingMoodRequest.kt @@ -0,0 +1,13 @@ +package com.example.remind.data.model.request + +data class WritingMoodRequest( + val detail: String, + val feelingType: String, + val localDate: String, + val moodActivities: List +) +data class MoodActivity( + val activityId: Int, + val detail: String, + val feelingType: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/ActivityListResponse.kt b/app/src/main/java/com/example/remind/data/model/response/ActivityListResponse.kt new file mode 100644 index 0000000..14d49aa --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/ActivityListResponse.kt @@ -0,0 +1,17 @@ +package com.example.remind.data.model.response + +data class ActivityListResponse( + val code: Int, + val `data`: ActivityData, + val message: String +) + +data class ActivityData( + val activities: List +) + +data class Activity( + val activityId: Int, + val iconImage: String, + val name: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/MedicingDailyInfoResponse.kt b/app/src/main/java/com/example/remind/data/model/response/MedicingDailyInfoResponse.kt index 5f42c31..5690613 100644 --- a/app/src/main/java/com/example/remind/data/model/response/MedicingDailyInfoResponse.kt +++ b/app/src/main/java/com/example/remind/data/model/response/MedicingDailyInfoResponse.kt @@ -1,5 +1,6 @@ package com.example.remind.data.model.response +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable @@ -16,9 +17,9 @@ data class MedicineData( @Serializable data class DailyTakingMedicineList( val importance: Int, - val isTaking: Boolean, + val isTaking: Boolean? = null, val medicinesType: String, - val notTakingReason: String, + val notTakingReason: String? = null, val prescriptionId: Int, - val takingTime: String + val takingTime: String? = null ) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/MoodChartResponse.kt b/app/src/main/java/com/example/remind/data/model/response/MoodChartResponse.kt new file mode 100644 index 0000000..507c4b5 --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/MoodChartResponse.kt @@ -0,0 +1,17 @@ +package com.example.remind.data.model.response + +data class MoodChartResponse( + val code: Int, + val `data`: Mood, + val message: String +) +data class Mood( + val hasNext: Boolean, + val moodChartDtos: List +) + +data class MoodChartDto( + val feeling: String, + val localDate: String, + val score: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/WritingMoodResponse.kt b/app/src/main/java/com/example/remind/data/model/response/WritingMoodResponse.kt new file mode 100644 index 0000000..e150072 --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/WritingMoodResponse.kt @@ -0,0 +1,10 @@ +package com.example.remind.data.model.response + +data class WritingMoodResponse( + val code: Int, + val `data`: MoodData, + val message: String +) +data class MoodData( + val moodId: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt index 9587b90..d348959 100644 --- a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt +++ b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt @@ -1,9 +1,13 @@ package com.example.remind.data.network.service import com.example.remind.data.model.request.SetMedicineInfoRequest +import com.example.remind.data.model.request.WritingMoodRequest +import com.example.remind.data.model.response.ActivityListResponse import com.example.remind.data.model.response.MedicineInfoResponse import com.example.remind.data.model.response.MedicingDailyInfoResponse +import com.example.remind.data.model.response.MoodChartResponse import com.example.remind.data.model.response.SetMedicineInfoResponse +import com.example.remind.data.model.response.WritingMoodResponse import com.example.remind.data.network.adapter.ApiResult import retrofit2.http.Body import retrofit2.http.GET @@ -24,8 +28,24 @@ interface PatientService { @Query("date") string:String, ): ApiResult - @POST("//taking-medicine") + @POST("/taking-medicine") suspend fun setMedicineInfo( @Body body: SetMedicineInfoRequest ): ApiResult + @GET("/activity") + suspend fun getActivityList( + ): ApiResult + + @POST("/mood") + suspend fun setTodayMood( + @Body body: WritingMoodRequest + ): ApiResult + + @GET("/mood/chart") + suspend fun getMoodChart( + @Query("year") year: Int, + @Query("month") month: Int, + @Query("day") day: Int, + @Query("size") size: Int, + ): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt index 04e5a58..5a6b8ce 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt @@ -1,12 +1,19 @@ package com.example.remind.data.repository.patient import com.example.remind.data.model.request.SetMedicineInfoRequest +import com.example.remind.data.model.request.WritingMoodRequest +import com.example.remind.data.model.response.ActivityListResponse import com.example.remind.data.model.response.MedicingDailyInfoResponse +import com.example.remind.data.model.response.MoodChartResponse import com.example.remind.data.model.response.OnBoardingResponse import com.example.remind.data.model.response.SetMedicineInfoResponse +import com.example.remind.data.model.response.WritingMoodResponse import com.example.remind.data.network.adapter.ApiResult interface PatientMedicineRepository { suspend fun getMedicineDaily(memberId: Int, date:String): ApiResult suspend fun setMedicineInfo(body: SetMedicineInfoRequest): ApiResult + suspend fun getActivityInfo(): ApiResult + suspend fun setTodayMood(body: WritingMoodRequest): ApiResult + suspend fun getMoodChart(year: Int, month: Int, day: Int, size: Int): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt index c006889..1ae235c 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt @@ -1,9 +1,13 @@ package com.example.remind.data.repository.patient import com.example.remind.data.model.request.SetMedicineInfoRequest +import com.example.remind.data.model.request.WritingMoodRequest +import com.example.remind.data.model.response.ActivityListResponse import com.example.remind.data.model.response.MedicingDailyInfoResponse +import com.example.remind.data.model.response.MoodChartResponse import com.example.remind.data.model.response.OnBoardingResponse import com.example.remind.data.model.response.SetMedicineInfoResponse +import com.example.remind.data.model.response.WritingMoodResponse import com.example.remind.data.network.adapter.ApiResult import com.example.remind.data.network.service.PatientService import javax.inject.Inject @@ -21,4 +25,21 @@ class PatientMedicineRepositoryImpl @Inject constructor( override suspend fun setMedicineInfo(body: SetMedicineInfoRequest): ApiResult { return service.setMedicineInfo(body) } + + override suspend fun getActivityInfo(): ApiResult { + return service.getActivityList() + } + + override suspend fun setTodayMood(body: WritingMoodRequest): ApiResult { + return service.setTodayMood(body) + } + + override suspend fun getMoodChart( + year: Int, + month: Int, + day: Int, + size: Int + ): ApiResult { + return service.getMoodChart(year, month, day, size) + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetActivityUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetActivityUseCase.kt new file mode 100644 index 0000000..7d55b8d --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetActivityUseCase.kt @@ -0,0 +1,14 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.response.ActivityListResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMedicineRepository +import javax.inject.Inject + +class GetActivityUseCase @Inject constructor( + private val patientMedicineRepository: PatientMedicineRepository +) { + suspend operator fun invoke(): ApiResult { + return patientMedicineRepository.getActivityInfo() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMoodChartUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMoodChartUseCase.kt new file mode 100644 index 0000000..e2d9535 --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMoodChartUseCase.kt @@ -0,0 +1,19 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.response.MoodChartResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMedicineRepository +import javax.inject.Inject + +class GetMoodChartUseCase @Inject constructor( + private val patientMedicineRepository: PatientMedicineRepository +) { + suspend operator fun invoke( + year: Int, + month: Int, + day: Int, + size: Int + ): ApiResult { + return patientMedicineRepository.getMoodChart(year, month, day, size) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SetTodayMoodUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SetTodayMoodUseCase.kt new file mode 100644 index 0000000..6b01e2e --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SetTodayMoodUseCase.kt @@ -0,0 +1,15 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.request.WritingMoodRequest +import com.example.remind.data.model.response.WritingMoodResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMedicineRepository +import javax.inject.Inject + +class SetTodayMoodUseCase @Inject constructor( + private val patientMedicineRepository: PatientMedicineRepository +) { + suspend operator fun invoke(body: WritingMoodRequest): ApiResult { + return patientMedicineRepository.setTodayMood(body) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/AuthGraph.kt b/app/src/main/java/com/example/remind/feature/screens/auth/AuthGraph.kt index 5cf22d6..9da930e 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/AuthGraph.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/AuthGraph.kt @@ -1,5 +1,6 @@ package com.example.remind.feature.screens.auth +import androidx.compose.runtime.Composable import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.compose.composable @@ -14,11 +15,13 @@ import com.example.remind.feature.screens.auth.onboarding.OnBoardingCheckDoctorS import com.example.remind.feature.screens.auth.onboarding.OnBoardingFinalScreen import com.example.remind.feature.screens.auth.onboarding.OnBoardingLoadingDoctorScreen import com.example.remind.feature.screens.auth.onboarding.OnBoardingPatienceScreen +import com.example.remind.feature.screens.auth.onboarding.OnBoardingViewModel import com.example.remind.feature.screens.auth.onboarding.SelectTypeScreen - +import com.example.remind.feature.screens.patience.home.HomeViewModel fun NavGraphBuilder.RegisterGraph( - navHostController: NavHostController + navHostController: NavHostController, + onBoardingViewModel: OnBoardingViewModel ) { navigation( route = Screens.Register.route, @@ -28,10 +31,10 @@ fun NavGraphBuilder.RegisterGraph( LoginScreen(navHostController) } composable(route = Screens.Register.SelectType.route) { - SelectTypeScreen(navHostController) + SelectTypeScreen(navHostController, onBoardingViewModel) } composable(route = Screens.Register.OnBoardingPatience.route) { - OnBoardingPatienceScreen(navHostController) + OnBoardingPatienceScreen(navHostController, onBoardingViewModel) } composable(route = Screens.Register.OnBoardingCheckDoctor.route) { OnBoardingCheckDoctorScreen(navHostController) @@ -43,7 +46,7 @@ fun NavGraphBuilder.RegisterGraph( OnBoardingCenterScreen() } composable(route = Screens.Register.OnBoardingFinal.route) { - OnBoardingFinalScreen(navHostController) + OnBoardingFinalScreen(navHostController,onBoardingViewModel) } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingCheckDoctor.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingCheckDoctor.kt index bb33174..19f0566 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingCheckDoctor.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingCheckDoctor.kt @@ -83,7 +83,8 @@ fun OnBoardingCheckDoctorScreen(navController: NavHostController) { district = "", protectorPhoneNumber = "01088644622", rolesType = "ROLE_DOCTOR", - fcmToken = "" + fcmToken = "", + doctorLicenseNumber = "" ) )) }, diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingFinal.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingFinal.kt index 01789b6..3056e0d 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingFinal.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingFinal.kt @@ -35,9 +35,9 @@ import kotlinx.coroutines.flow.collectLatest @Composable fun OnBoardingFinalScreen( - navController: NavHostController + navController: NavHostController, + viewModel: OnBoardingViewModel ) { - val viewModel: OnBoardingViewModel = hiltViewModel() val uiState by viewModel.uiState.collectAsStateWithLifecycle() val effectFlow = viewModel.effect val context = LocalContext.current diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt index 49de315..057e267 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt @@ -24,7 +24,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.PlatformTextStyle import androidx.compose.ui.text.TextStyle @@ -35,6 +34,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController import com.example.remind.R import com.example.remind.core.common.component.BasicOnBoardingAppBar @@ -46,9 +46,9 @@ import kotlinx.coroutines.flow.collectLatest @Composable fun OnBoardingPatienceScreen( - navController: NavHostController + navController: NavHostController, + viewModel:OnBoardingViewModel ) { - val viewModel: OnBoardingViewModel = hiltViewModel() val effectFlow = viewModel.effect val context = LocalContext.current var isChecked by remember{ mutableStateOf(false) } @@ -58,8 +58,6 @@ fun OnBoardingPatienceScreen( textState.value = newText } - val textFieldModifier = Modifier.padding(16.dp) - LaunchedEffect(true) { effectFlow.collectLatest { effect -> when(effect) { @@ -115,7 +113,8 @@ fun OnBoardingPatienceScreen( text = textState.value, roundedShape = 8.dp, hintText = stringResource(id = R.string.번호를_입력해주세요), - verticalPadding = 12.dp + topPadding = 12.dp, + bottomPadding = 12.dp ) Spacer(modifier = Modifier.height(12.dp)) @@ -139,7 +138,8 @@ fun OnBoardingPatienceScreen( district = "", protectorPhoneNumber = textState.value, rolesType = "ROLE_PATIENT", - fcmToken = "" + fcmToken = "", + doctorLicenseNumber = "" ) )) }, diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt index a398e77..592d7d6 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt @@ -32,6 +32,7 @@ class OnBoardingViewModel @Inject constructor( it ) } + getFcmToken() } } @@ -39,26 +40,22 @@ class OnBoardingViewModel @Inject constructor( override fun reduceState(event: OnBoardingContract.Event) { when(event) { is OnBoardingContract.Event.DoctorButtonClicked -> { - updateState(currentState.copy("ROLE_DOCTOR")) + updateState(currentState.copy(selectedType = "ROLE_DOCTOR")) saveUserType("ROLE_DOCTOR") } is OnBoardingContract.Event.CenterButtonClicked -> { - updateState(currentState.copy("ROLE_CENTER")) + updateState(currentState.copy(selectedType = "ROLE_CENTER")) saveUserType("ROLE_CENTER") } is OnBoardingContract.Event.PatienceButtonClicked -> { - updateState(currentState.copy("ROLE_PATIENT")) + updateState(currentState.copy(selectedType = "ROLE_PATIENT")) saveUserType("ROLE_PATIENT") } is OnBoardingContract.Event.NextButtonFinal -> { -// getFcmToken() -// postOnBoarding(event.onBoardingData.copy(fcmToken = currentState.fcmToken)) - if(currentState.selectedType == "ROLE_PATIENT") { - navigateToRoute(Screens.Register.OnBoardingFinal.route, Screens.Register.OnBoardingPatience.route, true) - getFcmToken() + viewModelScope.launch { postOnBoarding(event.onBoardingData.copy(fcmToken = currentState.fcmToken)) - } else if(currentState.selectedType == "ROLE_CENTER") { - navigateToRoute(Screens.Register.OnBoardingFinal.route, Screens.Register.OnBoardingCenter.route, true) + navigateToRoute(Screens.Register.OnBoardingFinal.route, Screens.Register.OnBoardingPatience.route, true) + Log.d("dklfawek", "${currentState.selectedType}") } } is OnBoardingContract.Event.NextButtonToPatience -> { @@ -110,10 +107,11 @@ class OnBoardingViewModel @Inject constructor( viewModelScope.launch { val fcmToken = tokenUseCase.invoke() updateState(currentState.copy(fcmToken = fcmToken)) + Log.d("alwkejflakwe", "${fcmToken}") } } - private fun postOnBoarding(data: OnBoardingRequest) { + private suspend fun postOnBoarding(data: OnBoardingRequest) { viewModelScope.launch { val result = onBoardingUserCase.invoke(data) when(result) { diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt index f1d9aff..feef723 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt @@ -1,5 +1,6 @@ package com.example.remind.feature.screens.auth.onboarding +import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -40,9 +41,9 @@ import kotlinx.coroutines.flow.collectLatest @Composable fun SelectTypeScreen( - navController: NavHostController + navController: NavHostController, + viewModel: OnBoardingViewModel ){ - val viewModel: OnBoardingViewModel = hiltViewModel() val uiState by viewModel.uiState.collectAsStateWithLifecycle() val effectFlow = viewModel.effect val context = LocalContext.current @@ -93,6 +94,7 @@ fun SelectTypeScreen( backgroundColor = if(uiState.selectedType == "ROLE_PATIENT") RemindTheme.colors.main_4 else RemindTheme.colors.slate_100, text = stringResource(id = R.string.환자용), onClick = { + Log.d("taaag", "환자용클릭됨") viewModel.setEvent(OnBoardingContract.Event.PatienceButtonClicked(context)) }, textColor = RemindTheme.colors.slate_700, diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt b/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt index 3acc52d..a1a03e3 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt @@ -5,21 +5,30 @@ import android.os.Build import androidx.annotation.RequiresApi import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.compose.NavHost import androidx.navigation.NavHostController import com.example.remind.app.Screens import androidx.navigation.compose.composable +import com.example.remind.feature.screens.patience.home.HomeCheeringScreen import com.example.remind.feature.screens.patience.home.HomeScreen +import com.example.remind.feature.screens.patience.home.HomeViewModel +import com.example.remind.feature.screens.patience.medicine.MedicineScreen import com.example.remind.feature.screens.patience.writing.WritingMoodStep1Screen +import com.example.remind.feature.screens.patience.writing.WritingMoodStep2FeelingScreen +import com.example.remind.feature.screens.patience.writing.WritingMoodStep2LastScreen import com.example.remind.feature.screens.patience.writing.WritingMoodStep2Screen import com.example.remind.feature.screens.patience.writing.WritingMoodStep3Screen +import com.example.remind.feature.screens.patience.writing.WritingViewModel @RequiresApi(Build.VERSION_CODES.O) @Composable fun PatienceGraph( navController: NavHostController, - modifier : Modifier + modifier: Modifier = Modifier ) { + val HomeviewModel: HomeViewModel = hiltViewModel() + val WritingviewModel: WritingViewModel = hiltViewModel() NavHost( navController = navController, route = Screens.Patience.route, @@ -29,13 +38,22 @@ fun PatienceGraph( HomeScreen(navController) } composable(route = Screens.Patience.Home.WritingMoodStep1.route) { - WritingMoodStep1Screen(navController) + WritingMoodStep1Screen(navController, WritingviewModel) } composable(route = Screens.Patience.Home.WritingMoodStep2.route) { - WritingMoodStep2Screen() + WritingMoodStep2Screen(navController, WritingviewModel) + } + composable(route = Screens.Patience.Home.WritingMoodStep2Feeling.route) { + WritingMoodStep2FeelingScreen(navController, WritingviewModel) + } + composable(route = Screens.Patience.Home.WritingMoodStep2Last.route) { + WritingMoodStep2LastScreen(navController, WritingviewModel) } composable(route = Screens.Patience.Home.WritingMoodStep3.route) { - WritingMoodStep3Screen() + WritingMoodStep3Screen(navController, WritingviewModel) + } + composable(route = Screens.Patience.Home.SplashCheering.route) { + HomeCheeringScreen(navController) } composable(route = Screens.Patience.MoodChart.route) { MoodChartScreen() diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeCheeringScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeCheeringScreen.kt index cae8319..df2fd8c 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeCheeringScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeCheeringScreen.kt @@ -3,14 +3,32 @@ package com.example.remind.feature.screens.patience.home import androidx.compose.foundation.Image import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavHostController import com.example.remind.R import com.example.remind.core.designsystem.theme.RemindTheme +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.collectLatest @Composable -fun HomeCheeringScreen() { +fun HomeCheeringScreen(navController: NavHostController) { + val viewModel: HomeViewModel = hiltViewModel() + val effectFlow = viewModel.effect + LaunchedEffect(true) { + delay(3000) + effectFlow.collectLatest { effect-> + when(effect) { + is HomeContract.Effect.NavigateTo -> { + navController.navigate(effect.destinaton, effect.navOptions) + } + else -> {} + } + } + } RemindTheme { Image( modifier = Modifier.fillMaxSize(), @@ -24,5 +42,4 @@ fun HomeCheeringScreen() { @Preview @Composable fun CheeringPreview() { - HomeCheeringScreen() } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt index c42a385..2057de1 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt @@ -7,7 +7,6 @@ import com.example.remind.core.base.UiEffect import com.example.remind.core.base.UiEvent import com.example.remind.core.base.UiState import com.example.remind.data.model.response.DailyTakingMedicineList -import com.example.remind.data.model.response.MedicineData class HomeContract { data class State( diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt index 9251417..c057dcf 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt @@ -82,9 +82,9 @@ fun HomeScreen(navController: NavHostController) { } } ) - var year = LocalDate.now().year - var month = LocalDate.now().monthValue - var day = LocalDate.now().dayOfMonth +// var year = LocalDate.now().year +// var month = LocalDate.now().monthValue +// var day = LocalDate.now().dayOfMonth var sendDate: String = "" var medicineTime: String = "" val dataSource = CalendarDataSource() @@ -210,16 +210,10 @@ fun HomeScreen(navController: NavHostController) { modifier = Modifier.fillMaxWidth() ) { itemsIndexed(uiState.medicineDailyData) {index, item -> - var timeText: String="" - if(item.medicinesType == "BREAKFAST"){ - timeText = "아침" - medicineTime = timeText - } else if(item.medicinesType == "LUNCH") { - timeText = "점심" - medicineTime = timeText - } else if(item.medicinesType == "DINNER") { - timeText = "저녁" - medicineTime = timeText + var timeText: String= when(item.medicinesType) { + "BREAKFAST" -> "아침" + "LUNCH" -> "점심" + else -> "저녁" } MedicineItem( time = timeText, @@ -228,9 +222,9 @@ fun HomeScreen(navController: NavHostController) { viewModel.setEvent(HomeContract.Event.showMediDialog) }, unadministeredClick = {}, - isTaking = item.isTaking, - isTakingTime = item.takingTime, - notTakingReason = item.notTakingReason + isTaking = item.isTaking ?: false, + isTakingTime = item.takingTime ?: "", + notTakingReason = item.notTakingReason ?: "" ) } } @@ -248,7 +242,7 @@ fun HomeScreen(navController: NavHostController) { Spacer(modifier = Modifier.height(10.dp)) EmptyTodayMoodContainer( clickToWrite = { - viewModel.navigateToWriting() + viewModel.setEvent(HomeContract.Event.WritingButtonClicked(context)) } ) Spacer(modifier = Modifier.height(80.dp)) @@ -402,7 +396,7 @@ fun DayItem( text = date.date.dayOfMonth.toString(), modifier = Modifier .align(Alignment.CenterHorizontally) - .padding(vertical = 1.dp, horizontal = 7.dp) + .padding(vertical = 2.dp, horizontal = 9.dp) .background(color = RemindTheme.colors.white, shape = CircleShape), style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.slate_800) ) @@ -433,10 +427,6 @@ fun EmptyMedicineList( } } -fun MedicineList() { - -} - @Composable fun EmptyTodayMoodContainer( modifier: Modifier = Modifier, diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt index de161b5..c80085a 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt @@ -8,17 +8,13 @@ import com.example.remind.app.Screens import com.example.remind.core.base.BaseViewModel import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.network.adapter.ApiResult -import com.example.remind.data.network.interceptor.TokenManager import com.example.remind.domain.usecase.patience_usecase.PatientMedicineDailyUseCase import com.example.remind.domain.usecase.patience_usecase.SetMedicineInfoUseCase -import com.example.remind.feature.screens.auth.login.LoginContract import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class HomeViewModel @Inject constructor( - private val tokenManager: TokenManager, private val patientMedicineDailyUseCase: PatientMedicineDailyUseCase, private val setMedicineInfoUseCase: SetMedicineInfoUseCase ): BaseViewModel( @@ -27,7 +23,11 @@ class HomeViewModel @Inject constructor( override fun reduceState(event: HomeContract.Event) { when(event) { is HomeContract.Event.WritingButtonClicked -> { - navigateToWriting() + navigateToRoute( + destination = Screens.Patience.Home.WritingMoodStep1.route, + current = Screens.Patience.Home.route, + inclusiveData = false + ) } is HomeContract.Event.showSosDialog -> { updateState(currentState.copy(sosDialogState = true)) @@ -45,25 +45,28 @@ class HomeViewModel @Inject constructor( setSosCall(event.context, event.number) } is HomeContract.Event.SendNotTakingReason -> { + navigateToRoute( + destination = Screens.Patience.Home.SplashCheering.route, + current = Screens.Patience.Home.route, + inclusiveData = false + ) sendNotTakingReason(event.medicineTime, event.date, event.notTakingReason) } } } - - - - fun navigateToWriting() { + fun navigateToRoute(destination: String, current: String, inclusiveData: Boolean) { postEffect( HomeContract.Effect.NavigateTo( - destinaton = Screens.Patience.Home.WritingMoodStep1.route, + destinaton = destination, navOptions = navOptions { - popUpTo(Screens.Patience.Home.route) { - inclusive = false + popUpTo(current) { + inclusive = inclusiveData } } ) ) } + fun setSosCall( context: Context, number:String) { postEffect( HomeContract.Effect.getCall(context, number) diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmDialog.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmDialog.kt new file mode 100644 index 0000000..3f1b239 --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmDialog.kt @@ -0,0 +1,209 @@ +package com.example.remind.feature.screens.patience.medicine + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +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.shape.RoundedCornerShape +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.material3.Button +import androidx.compose.material3.Checkbox +import androidx.compose.material3.CheckboxDefaults +import androidx.compose.material3.MaterialTheme +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.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import com.example.remind.R +import com.example.remind.core.designsystem.theme.RemindTheme +import java.text.DecimalFormat +import java.time.LocalTime + +@Composable +fun AlarmDialog ( + modifier: Modifier = Modifier, + onDismissClick: () -> Unit, + onConfirmClick: () -> Unit, + showDialog:Boolean, +) { + +} + +@Composable +fun AlarmContent( + modifier: Modifier = Modifier, + onDismissClick: () -> Unit, + onConfirmClick: () -> Unit, +) { + Box( + modifier = modifier + .fillMaxWidth() + .background( + color = RemindTheme.colors.white, + shape = RoundedCornerShape(10.dp) + ) + ) { + Text( + modifier = Modifier + .align(Alignment.TopCenter) + .padding(top = 9.13.dp), + textAlign = TextAlign.Center, + text = stringResource(id = R.string.알림_추가), + style = RemindTheme.typography.b1Bold.copy(color = RemindTheme.colors.text) + ) + + Icon( + modifier = modifier + .align(Alignment.TopEnd) + .padding(top = 8.83.dp, end = 11.dp) + .clickable(onClick = onDismissClick), + painter = painterResource(id = R.drawable.ic_close), + tint = RemindTheme.colors.icon, + contentDescription = null + ) + } +} + +@Composable +fun CustomTimePicker( + initialTime: LocalTime = LocalTime.now(), + onTimeSelected: (LocalTime) -> Unit +) { + var selectedHour by remember { mutableStateOf(if (initialTime.hour % 12 == 0) 12 else initialTime.hour % 12) } + var selectedMinute by remember { mutableStateOf(initialTime.minute) } + var isAM by remember { mutableStateOf(initialTime.hour < 12) } + val df = DecimalFormat("00") + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Row(verticalAlignment = Alignment.CenterVertically) { + androidx.compose.material3.Text( + text = if (isAM) "오전" else "오후", + modifier = Modifier + .padding(start = 16.dp) + .clickable( + onClick = { isAM = !isAM }, + interactionSource = remember { MutableInteractionSource() }, + indication = null + ), + style = MaterialTheme.typography.bodyLarge.copy(fontWeight = FontWeight.Bold) + ) + TimePicker( + value = df.format(selectedHour).toInt(), + range = 1..12, + onValueChange = { selectedHour = it } + ) + androidx.compose.material3.Text(":", fontWeight = FontWeight.Bold, modifier = Modifier.padding(8.dp)) + TimePicker( + value = selectedMinute, + range = 0..59, + onValueChange = { selectedMinute = it } + ) + + } + Spacer(modifier = Modifier.height(16.dp)) + Button(onClick = { + val hour24 = if (isAM) { + if (selectedHour == 12) 0 else selectedHour + } else { + if (selectedHour == 12) 12 else selectedHour + 12 + } + onTimeSelected(LocalTime.of(hour24, selectedMinute)) + }) { + androidx.compose.material3.Text("Select Time") + } + } +} + +@Composable +fun SelectDay( + modifier: Modifier = Modifier, + checked: Boolean, +) { + val dayList = listOf("일", "월", "화", "수", "목", "금", "토") + var isChecked by remember{ mutableStateOf(false) } + Column( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 18.dp) + ) { + Row( + modifier = modifier + .fillMaxWidth() + ) { + Text( + text = stringResource(id = R.string.요일), + style = RemindTheme.typography.b2Bold.copy(color = RemindTheme.colors.text) + ) + Text( + modifier = modifier.padding(start = 14.dp), + text = stringResource(id = R.string.요일), + style = RemindTheme.typography.b2Bold.copy(color = RemindTheme.colors.main_7) + ) + Checkbox( + modifier = modifier.padding(start = 4.dp), + checked = isChecked, + colors = CheckboxDefaults.colors( + checkedColor = RemindTheme.colors.main_6, + uncheckedColor = Color(0xFF6B7280), + checkmarkColor = RemindTheme.colors.white + ), + onCheckedChange = {isChecked = it} + ) + } + Row( + modifier = modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceEvenly + ) { + for(i in 0..6) { + + } + } + } +} + +@Composable +fun DayListComponent( + modifier: Modifier = Modifier, + text: String, + backgroundColor: Color, + borderColor: Color, + onClick: () -> Unit +) { + Box( + modifier = modifier + .background(color = backgroundColor, shape = RoundedCornerShape(8.dp)) + .border(width = 1.dp, color = borderColor, shape = RoundedCornerShape(8.dp)) + .clickable( + onClick = onClick, + interactionSource = remember { MutableInteractionSource() }, + indication = null + ), + contentAlignment = Alignment.Center + ) { + Text( + modifier = modifier.padding(10.dp), + text = text, + style = RemindTheme.typography.h2Medium.copy(RemindTheme.colors.text) + ) + } +} diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/MedicineScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt similarity index 97% rename from app/src/main/java/com/example/remind/feature/screens/patience/MedicineScreen.kt rename to app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt index 480abe3..b0ed002 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/MedicineScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt @@ -1,4 +1,4 @@ -package com.example.remind.feature.screens.patience +package com.example.remind.feature.screens.patience.medicine import androidx.compose.foundation.Image import androidx.compose.foundation.border diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/TimePicker.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/TimePicker.kt new file mode 100644 index 0000000..03d4153 --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/TimePicker.kt @@ -0,0 +1,55 @@ +package com.example.remind.feature.screens.patience.medicine + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.* +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.KeyboardArrowDown +import androidx.compose.material.icons.filled.KeyboardArrowUp +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import java.text.DecimalFormat +import java.time.LocalTime + +@Composable +fun TimePicker( + value: Int, + range: IntRange, + onValueChange: (Int) -> Unit +) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + IconButton(onClick = { + if (value < range.last) onValueChange(value + 1) + }) { + Icon(imageVector = Icons.Default.KeyboardArrowUp, contentDescription = null) + } + Text(text = value.toString(), style = MaterialTheme.typography.bodyLarge) + IconButton(onClick = { + if (value > range.first) onValueChange(value - 1) + }) { + Icon(imageVector = Icons.Default.KeyboardArrowDown, contentDescription = null) + } + } +} + +@Preview(showBackground = true) +@Composable +fun TimePickerExample() { + var selectedTime by remember { mutableStateOf(null) } + + CustomTimePicker( + initialTime = selectedTime ?: LocalTime.now(), + onTimeSelected = { time -> + selectedTime = time + } + ) + + selectedTime?.let { + Text("Selected Time: ${it.hour % 12}:${it.minute} ${if (it.hour < 12) "AM" else "PM"}") + } +} diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt index cebee94..8b5fbca 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt @@ -6,17 +6,35 @@ import androidx.navigation.NavOptionsBuilder import com.example.remind.core.base.UiEffect import com.example.remind.core.base.UiEvent import com.example.remind.core.base.UiState +import com.example.remind.data.model.request.MoodActivity +import com.example.remind.data.model.response.Activity class WritingContract { data class State( - val selectFeelingType: String? = null, + val totalFeelingType: String = "", + val ActivityList: List = emptyList(), + val MoodActivityList: List = emptyList(), + val detail: String = "", + val activityId: Int = 0, + val activityName: String = "", + val feelingType: String = "", + val thanksToDetail: String = "" ): UiState sealed class Event: UiEvent { data class FeelingButtonClicked(val feelingType: String): Event() data class NextButtonClicked(val destinationRoute: String, val currentRoute: String): Event() data class PreviousButtonClicked(val destinationRoute: String, val currentRoute: String): Event() + data class ActivityButtonClicked(val activityId: Int, val activityName: String): Event() + data class FeelingActivityButtonClicked(val feelingType: String): Event() + data class StoreFeelingListItem( + val activityData: MoodActivity, + val destinationRoute: String, + val currentRoute: String + ): Event() data class NavigateToHome(val context: Context): Event() + data class NavigateToStep2(val destinationRoute: String, val currentRoute: String): Event() + data class SendInfoButton(val destinationRoute: String, val currentRoute: String, val localDate: String, val detail:String): Event() } sealed class Effect: UiEffect { diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep1Screen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep1Screen.kt index 84b34fd..1c40de4 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep1Screen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep1Screen.kt @@ -1,16 +1,12 @@ package com.example.remind.feature.screens.patience.writing -import androidx.compose.foundation.Image -import androidx.compose.foundation.Indication import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.clickable 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.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -21,32 +17,28 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.Text -import androidx.compose.material.ripple.rememberRipple import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController import com.example.remind.R import com.example.remind.app.Screens import com.example.remind.core.common.component.BasicButton +import com.example.remind.core.common.component.IconContainer import com.example.remind.core.common.component.StepComponent import com.example.remind.core.designsystem.theme.RemindTheme import com.example.remind.data.model.FeelingScoreModel import kotlinx.coroutines.flow.collectLatest @Composable -fun WritingMoodStep1Screen(navController: NavHostController) { - val viewModel: WritingViewModel = hiltViewModel() +fun WritingMoodStep1Screen(navController: NavHostController, viewModel: WritingViewModel) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() val effectFlow = viewModel.effect val feelingList = listOf( @@ -79,7 +71,10 @@ fun WritingMoodStep1Screen(navController: NavHostController) { Spacer(modifier = Modifier.height(24.dp)) IconButton( onClick = { - viewModel.navigateToHome() + viewModel.setEvent(WritingContract.Event.PreviousButtonClicked( + Screens.Patience.Home.route, + Screens.Patience.Home.WritingMoodStep1.route + )) } ) { Icon( @@ -103,7 +98,6 @@ fun WritingMoodStep1Screen(navController: NavHostController) { style = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.slate_400) ) Spacer(modifier = Modifier.weight(1f)) - //이모티콘 박스 Box( modifier = Modifier .background(color = RemindTheme.colors.white) @@ -124,7 +118,7 @@ fun WritingMoodStep1Screen(navController: NavHostController) { IconContainer( feelingScoreModel = feelingList.get(i), backgroundColor = - if(uiState.selectFeelingType == feelingList.get(i).text) RemindTheme.colors.main_4 else RemindTheme.colors.white, + if(uiState.totalFeelingType == feelingList.get(i).text) RemindTheme.colors.main_4 else RemindTheme.colors.white, onClick = { viewModel.setEvent(WritingContract.Event.FeelingButtonClicked(feelingList.get(i).text)) } @@ -143,16 +137,16 @@ fun WritingMoodStep1Screen(navController: NavHostController) { ), text = stringResource(id = R.string.다음), RoundedCorner = 12.dp, - backgroundColor = if(uiState.selectFeelingType != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, - textColor = if(uiState.selectFeelingType != null) RemindTheme.colors.white else RemindTheme.colors.slate_300, + backgroundColor = if(uiState.totalFeelingType != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + textColor = if(uiState.totalFeelingType != null) RemindTheme.colors.white else RemindTheme.colors.slate_300, verticalPadding = 13.dp, onClick = { - viewModel.navigateToRoute( - destination = Screens.Patience.Home.WritingMoodStep2.route, - current = Screens.Patience.Home.WritingMoodStep1.route - ) + viewModel.setEvent(WritingContract.Event.NextButtonClicked( + Screens.Patience.Home.WritingMoodStep2.route, + Screens.Patience.Home.WritingMoodStep1.route + )) }, - textStyle = RemindTheme.typography.b2Bold.copy(color = RemindTheme.colors.white) + textStyle = RemindTheme.typography.b2Bold ) } } @@ -173,47 +167,6 @@ fun StepContainer( } } - -//아이콘 컨테이너 만듬 -@Composable -fun IconContainer( - modifier: Modifier = Modifier, - feelingScoreModel: FeelingScoreModel, - backgroundColor: Color, - onClick: () -> Unit -) { - Box( - modifier = modifier - .background(color = backgroundColor, shape = RoundedCornerShape(16.dp)) - .clickable(onClick = onClick) - ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally - ) { - Image( - modifier = modifier - .padding( - top = 18.dp, - start = 15.dp, - end = 15.dp, - bottom = 16.dp - ) - .size( - width = 25.dp, - height = 25.dp - ), - painter = painterResource(id = feelingScoreModel.imgeRes), - contentDescription = null - ) - Text( - modifier = modifier.padding(bottom = 15.dp), - text = feelingScoreModel.feeling, - style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.slate_700) - ) - } - } -} - @Preview(showBackground = true) @Composable fun WritingPreview() { diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt new file mode 100644 index 0000000..998fe9f --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt @@ -0,0 +1,184 @@ +package com.example.remind.feature.screens.patience.writing + +import android.widget.Toast +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.shape.RoundedCornerShape +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +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.unit.dp +import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavHostController +import com.example.remind.R +import com.example.remind.app.Screens +import com.example.remind.core.common.component.BasicButton +import com.example.remind.core.common.component.IconContainer +import com.example.remind.core.common.component.RemindTextField +import com.example.remind.core.designsystem.theme.RemindTheme +import com.example.remind.data.model.FeelingScoreModel +import com.example.remind.data.model.request.MoodActivity +import kotlinx.coroutines.flow.collectLatest + +@Composable +fun WritingMoodStep2FeelingScreen(navController: NavHostController, viewModel: WritingViewModel) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val effectFlow = viewModel.effect + val context = LocalContext.current + val feelingList = listOf( + FeelingScoreModel(R.drawable.ic_verygood, "정말 좋음", "VERY_GOOD"), + FeelingScoreModel(R.drawable.ic_good, "좋음", "GOOD"), + FeelingScoreModel(R.drawable.ic_normal, "보통", "NORMAL"), + FeelingScoreModel(R.drawable.ic_bad, "나쁨", "BAD"), + FeelingScoreModel(R.drawable.ic_terrible, "끔찍함", "TERRIBLE") + ) + val textState = remember { mutableStateOf("") } + val handleTextChange = { newText: String -> + textState.value = newText + } + + LaunchedEffect(true) { + effectFlow.collectLatest { effect -> + when(effect) { + is WritingContract.Effect.NavigateTo -> { + navController.navigate(effect.destinaton, effect.navOptions) + } + is WritingContract.Effect.Toastmessage -> { + Toast.makeText(context, effect.message, Toast.LENGTH_SHORT).show() + } + else -> {} + } + } + } + + RemindTheme { + Column( + modifier = Modifier.padding(vertical = 20.dp) + ) { + Spacer(modifier = Modifier.height(24.dp)) + IconButton( + onClick = { + viewModel.setEvent(WritingContract.Event.PreviousButtonClicked( + Screens.Patience.Home.WritingMoodStep1.route, + Screens.Patience.Home.WritingMoodStep2.route + )) + } + ) { + Icon( + painter = painterResource(id = R.drawable.ic_arrowleft), + contentDescription = null, + tint = RemindTheme.colors.icon + ) + + } + StepContainer2(modifier = Modifier.padding(top = 31.dp)) + Text( + modifier = Modifier.padding(top = 16.dp), + text = stringResource(id = R.string.오늘_하루_어떤_활동을_하셨나요_), + style = RemindTheme.typography.h1Bold.copy(color = RemindTheme.colors.text, lineHeight = 44.sp) + ) + Text( + modifier = Modifier.padding(top = 12.dp), + text = stringResource(id = R.string.오늘의_활동을_선택해주세요), + style = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.slate_400) + ) + Text( + modifier = Modifier.padding(top = 47.dp), + textAlign = TextAlign.Center, + text = stringResource(id = R.string.해당_활동이_어떤_영향을_주었나요), + style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.slate_600) + ) + Spacer(modifier = Modifier.height(7.dp)) + Box( + modifier = Modifier + .background(color = RemindTheme.colors.white) + .border( + width = 1.dp, + shape = RoundedCornerShape(18.dp), + color = RemindTheme.colors.grayscale_1 + ) + .padding(start = 20.dp, end = 20.dp) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 15.dp, bottom = 15.dp), + horizontalArrangement = Arrangement.SpaceEvenly + ) { + for(i in 0..4) { + IconContainer( + feelingScoreModel = feelingList.get(i), + backgroundColor = + if(uiState.feelingType == feelingList.get(i).text) RemindTheme.colors.main_4 else RemindTheme.colors.white, + onClick = { + viewModel.setEvent(WritingContract.Event.FeelingActivityButtonClicked( + feelingList.get(i).text + )) + } + ) + } + } + } + Text( + modifier = Modifier.padding(top = 19.dp), + text = stringResource(id = R.string.활동을_할_때), + style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.slate_600) + ) + Spacer(modifier = Modifier.height(6.dp)) + RemindTextField( + modifier = Modifier + .fillMaxWidth() + .height(80.dp), + onTextChanged = handleTextChange, + text = textState.value, + roundedShape = 18.dp, + hintText = stringResource(id = R.string.힌트_오랜만에_), + topPadding = 15.dp, + bottomPadding = 0.dp + ) + Spacer(modifier = Modifier.weight(1f)) + BasicButton( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 32.dp), + text = stringResource(id = R.string.다음), + RoundedCorner = 12.dp, + backgroundColor = if(uiState.feelingType != "") RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + textColor = if(uiState.feelingType != "") RemindTheme.colors.white else RemindTheme.colors.slate_300, + verticalPadding = 13.dp, + onClick = { + viewModel.setEvent(WritingContract.Event.StoreFeelingListItem( + activityData = MoodActivity( + uiState.activityId, + uiState.feelingType, + textState.value + ), + destinationRoute = Screens.Patience.Home.WritingMoodStep2Last.route, + currentRoute = Screens.Patience.Home.WritingMoodStep2Feeling.route + )) + }, + textStyle = RemindTheme.typography.b2Bold + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt new file mode 100644 index 0000000..e7635a5 --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt @@ -0,0 +1,281 @@ +package com.example.remind.feature.screens.patience.writing + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +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.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavHostController +import com.bumptech.glide.integration.compose.ExperimentalGlideComposeApi +import com.bumptech.glide.integration.compose.GlideImage +import com.example.remind.R +import com.example.remind.app.Screens +import com.example.remind.core.common.component.BasicButton +import com.example.remind.core.designsystem.theme.RemindTheme +import com.example.remind.data.model.FeelingScoreModel +import kotlinx.coroutines.flow.collectLatest + + +@Composable +fun WritingMoodStep2LastScreen(navController: NavHostController, viewModel: WritingViewModel) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val effectFlow = viewModel.effect + val scrollState = rememberScrollState() + + val feelingList = listOf( + FeelingScoreModel(R.drawable.ic_verygood, "정말 좋음", "VERY_GOOD", "기분이 정말 좋았어요!"), + FeelingScoreModel(R.drawable.ic_good, "좋음", "GOOD", "기분이 좋았어요!"), + FeelingScoreModel(R.drawable.ic_normal, "보통", "NORMAL", "기분이 보통이었어요!"), + FeelingScoreModel(R.drawable.ic_bad, "나쁨", "BAD", "기분이 나빴어요."), + FeelingScoreModel(R.drawable.ic_terrible, "끔찍함", "TERRIBLE", "기분이 매우 안좋았어요.") + ) + fun findActivityImage(activityId: Int): String? { + val moodActivity = uiState.ActivityList.find { it.activityId == activityId} + return moodActivity?.iconImage + } + fun findActivityName(activityId: Int): String? { + val moodActivity = uiState.ActivityList.find { it.activityId == activityId} + return moodActivity?.name + } + fun findMoodImage(feelingType: String): Int? { + val moodFeeling = feelingList.find { it.text == feelingType} + return moodFeeling?.imgeRes + } + fun findMoodDescription(feelingType: String): String? { + val moodFeeling = feelingList.find { it.text == feelingType} + return moodFeeling?.description + } + LaunchedEffect(true) { + effectFlow.collectLatest { effect -> + when(effect) { + is WritingContract.Effect.NavigateTo -> { + navController.navigate(effect.destinaton, effect.navOptions) + } + else -> {} + } + } + } + + RemindTheme { + Column( + modifier = Modifier + .fillMaxSize() + .verticalScroll(scrollState) + .background(color = RemindTheme.colors.white) + .padding(horizontal = 20.dp) + ) { + Spacer(modifier = Modifier.height(24.dp)) + IconButton( + onClick = { + viewModel.setEvent(WritingContract.Event.PreviousButtonClicked( + Screens.Patience.Home.route, + Screens.Patience.Home.WritingMoodStep1.route + )) + } + ) { + Icon( + painter = painterResource(id = R.drawable.ic_arrowleft), + contentDescription = null, + tint = RemindTheme.colors.icon + ) + + } + StepContainer2( + modifier = Modifier.padding(top = 31.dp) + ) + Text( + modifier = Modifier.padding(top = 16.dp), + text = stringResource(id = R.string.오늘_하루_어떤_활동을_하셨나요_), + style = RemindTheme.typography.h1Bold.copy(color = RemindTheme.colors.text, lineHeight = 44.sp) + ) + Text( + modifier = Modifier.padding(top = 12.dp), + text = stringResource(id = R.string.오늘의_활동은_최대_3개까지), + style = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.slate_400) + ) + if(uiState.MoodActivityList.size >0) { + LazyColumn( + modifier = Modifier.padding(start = 20.dp, end = 20.dp, top = 70.dp), + ) { + itemsIndexed(uiState.MoodActivityList) {index, item -> + ActivityListContainer( + modifier = Modifier.padding(bottom = 10.dp), + activityImage = findActivityImage(item.activityId)!!, + activityText = findActivityName(item.activityId)!!, + moodImage = findMoodImage(item.feelingType)!!, + moodDescription = findMoodDescription(item.feelingType)!!, + detail = item.detail + ) + } + } + } + PlusContainer( + modifier = Modifier.padding(top = 10.dp), + onClick = { + viewModel.setEvent(WritingContract.Event.NavigateToStep2( + Screens.Patience.Home.WritingMoodStep2Last.route, + Screens.Patience.Home.WritingMoodStep2.route + )) + } + ) + Spacer(modifier = Modifier.weight(1f)) + BasicButton( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 32.dp), + text = stringResource(id = R.string.다음), + RoundedCorner = 12.dp, + backgroundColor = RemindTheme.colors.main_6, + textColor = RemindTheme.colors.white, + verticalPadding = 13.dp, + onClick = { + viewModel.setEvent(WritingContract.Event.NextButtonClicked( + Screens.Patience.Home.WritingMoodStep3.route, + Screens.Patience.Home.WritingMoodStep2Last.route + )) + }, + textStyle = RemindTheme.typography.b2Bold + ) + } + } +} + + +@OptIn(ExperimentalGlideComposeApi::class) +@Composable +fun ActivityListContainer( + modifier: Modifier = Modifier, + activityImage: String, + activityText: String, + moodImage: Int, + moodDescription: String, + detail: String +) { + Box( + modifier = modifier + .fillMaxWidth() + .border( + width = 1.dp, + color = RemindTheme.colors.grayscale_1, + shape = RoundedCornerShape(8.dp) + ) + .background(color = RemindTheme.colors.white, shape = RoundedCornerShape(8.dp)) + ) { + Row( + modifier = modifier.padding(horizontal = 20.dp) + ) { + Column( + modifier = modifier.padding(top = 6.dp, bottom = 13.dp), + verticalArrangement = Arrangement.Center + ) { + GlideImage( + modifier = modifier.padding(bottom = 6.dp), + model = activityImage, + contentDescription = null + ) + Text( + modifier = modifier + .padding(horizontal = 20.dp, vertical = 2.5.dp) + .background( + color = RemindTheme.colors.main_2, + shape = RoundedCornerShape(18.dp) + ), + text = activityText, + style = RemindTheme.typography.c2Medium.copy(color = RemindTheme.colors.text) + ) + } + Column( + modifier = modifier.padding(start= 43.dp), + verticalArrangement = Arrangement.Center + ) { + Row( + horizontalArrangement = Arrangement.Start, + verticalAlignment = Alignment.CenterVertically + ) { + Image( + modifier = modifier.size(width = 15.dp, height = 21.dp), + painter = painterResource(id = moodImage), + contentDescription = null + ) + Text( + modifier = modifier + .padding(start = 3.dp, bottom = 6.dp), + text = moodDescription, + style = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.slate_600) + ) + } + Text( + text = detail, + style = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.slate_500) + ) + } + } + + } +} + +@Composable +fun PlusContainer( + modifier: Modifier = Modifier, + onClick: () -> Unit +) { + Box( + modifier = modifier + .fillMaxWidth() + .background(color = RemindTheme.colors.white, shape = RoundedCornerShape(8.dp)) + .border( + width = 1.dp, + color = RemindTheme.colors.grayscale_1, + shape = RoundedCornerShape(8.dp) + ) + .clickable( + onClick = onClick, + interactionSource = remember { MutableInteractionSource() }, + indication = null + ) + ) { + Column( + modifier = modifier.padding(vertical = 13.dp), + verticalArrangement = Arrangement.Center, + ) { + Image( + painter = painterResource(id = R.drawable.ic_plus), + contentDescription = null + ) + Text( + modifier = modifier.padding(top = 6.dp), + text = stringResource(id = R.string.활동_추가하기), + style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.white) + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt index 5199cfe..55d94ac 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt @@ -1,8 +1,213 @@ package com.example.remind.feature.screens.patience.writing +import android.widget.Toast +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +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.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid +import androidx.compose.foundation.lazy.grid.itemsIndexed +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +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.unit.dp +import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavHostController +import com.bumptech.glide.integration.compose.ExperimentalGlideComposeApi +import com.bumptech.glide.integration.compose.GlideImage +import com.example.remind.R import com.example.remind.app.Screens +import com.example.remind.core.common.component.BasicButton +import com.example.remind.core.common.component.StepComponent +import com.example.remind.core.designsystem.theme.RemindTheme +import com.example.remind.data.model.request.MoodActivity +import com.example.remind.data.model.response.Activity +import com.example.remind.feature.screens.auth.login.LoginContract +import kotlinx.coroutines.flow.collectLatest + @Composable -fun WritingMoodStep2Screen() { +fun WritingMoodStep2Screen(navController: NavHostController, viewModel: WritingViewModel) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val effectFlow = viewModel.effect + val context = LocalContext.current + + LaunchedEffect(true) { + effectFlow.collectLatest { effect -> + when(effect) { + is WritingContract.Effect.NavigateTo -> { + navController.navigate(effect.destinaton, effect.navOptions) + } + is WritingContract.Effect.Toastmessage -> { + Toast.makeText(context, effect.message, Toast.LENGTH_SHORT).show() + } + else -> {} + } + } + } + + RemindTheme { + Column( + modifier = Modifier + .fillMaxSize() + .background(color = RemindTheme.colors.white) + .padding( + start = 20.dp, + end = 20.dp + ) + ) { + Spacer(modifier = Modifier.height(24.dp)) + IconButton( + onClick = { + viewModel.setEvent(WritingContract.Event.PreviousButtonClicked( + Screens.Patience.Home.WritingMoodStep1.route, + Screens.Patience.Home.WritingMoodStep2.route + )) + } + ) { + Icon( + painter = painterResource(id = R.drawable.ic_arrowleft), + contentDescription = null, + tint = RemindTheme.colors.icon + ) + + } + StepContainer2(modifier = Modifier.padding(top = 31.dp)) + Text( + modifier = Modifier.padding(top = 16.dp), + text = stringResource(id = R.string.오늘_하루_어떤_활동을_하셨나요_), + style = RemindTheme.typography.h1Bold.copy(color = RemindTheme.colors.text, lineHeight = 44.sp) + ) + Text( + modifier = Modifier.padding(top = 12.dp), + text = stringResource(id = R.string.오늘의_활동을_선택해주세요), + style = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.slate_400) + ) + Spacer(modifier = Modifier.height(40.dp)) + Row( + modifier = Modifier.fillMaxWidth() + ) { + Spacer(modifier = Modifier.weight(1f)) + BasicButton( + text = stringResource(id = R.string.활동_편집), + RoundedCorner = 20.dp, + backgroundColor = RemindTheme.colors.main_6, + textColor = RemindTheme.colors.slate_50, + verticalPadding = 3.dp, + onClick = { }, + textStyle = RemindTheme.typography.c3Bold + ) + } + Box( + modifier = Modifier.fillMaxWidth() + ) { + LazyHorizontalGrid( + rows = GridCells.Fixed(2) + ) { + itemsIndexed(uiState.ActivityList) {index, item -> + ImageContainerContent( + background = if(uiState.activityId != null) RemindTheme.colors.main_4 else RemindTheme.colors.white, + onClick = { + viewModel.setEvent(WritingContract.Event.ActivityButtonClicked( + item.activityId, + item.name + )) + }, + imageUrl = item.iconImage, + name = item.name + ) + } + } + } + Spacer(modifier = Modifier.weight(1f)) + BasicButton( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 32.dp), + text = stringResource(id = R.string.다음), + RoundedCorner = 12.dp, + backgroundColor = if(uiState.activityId != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + textColor = if(uiState.activityId != null) RemindTheme.colors.white else RemindTheme.colors.slate_300, + verticalPadding = 13.dp, + onClick = { + viewModel.setEvent(WritingContract.Event.NextButtonClicked( + Screens.Patience.Home.WritingMoodStep2Feeling.route, + Screens.Patience.Home.WritingMoodStep2.route + )) + }, + textStyle = RemindTheme.typography.b2Bold + ) + } + } +} -} \ No newline at end of file +@OptIn(ExperimentalGlideComposeApi::class) +@Composable +fun ImageContainerContent( + modifier: Modifier = Modifier, + background: Color, + onClick: () -> Unit, + imageUrl: String, + name: String +) { + Box( + modifier = modifier + .fillMaxWidth() + .background(color = background, shape = RoundedCornerShape(12.dp)) + .clickable( + onClick = onClick + ) + ) { + Column( + modifier = modifier + .padding(vertical = 8.dp, horizontal = 10.dp), + verticalArrangement = Arrangement.Center + ) { + GlideImage( + modifier = modifier.padding(bottom = 6.dp), + model = imageUrl, + contentDescription = null + ) + Text( + text = name, + textAlign = TextAlign.Center, + style = RemindTheme.typography.c3Bold.copy(color = RemindTheme.colors.slate_700) + ) + } + } +} + +@Composable +fun StepContainer2( + modifier: Modifier = Modifier +) { + Row( + modifier = modifier + ) { + StepComponent(text = 1, backgroundColor = RemindTheme.colors.main_6, textColor = RemindTheme.colors.slate_50) + Spacer(modifier = modifier.width(6.dp)) + StepComponent(text = 2, backgroundColor = RemindTheme.colors.main_6, textColor = RemindTheme.colors.slate_50) + Spacer(modifier = modifier.width(6.dp)) + StepComponent(text = 3, backgroundColor = RemindTheme.colors.slate_500, textColor = RemindTheme.colors.slate_400) + } +} diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt index d31cb07..32c0831 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt @@ -1,8 +1,149 @@ package com.example.remind.feature.screens.patience.writing +import android.widget.Toast +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavHostController +import com.example.remind.R +import com.example.remind.app.Screens +import com.example.remind.core.common.component.BasicButton +import com.example.remind.core.common.component.RemindTextField +import com.example.remind.core.common.component.StepComponent +import com.example.remind.core.designsystem.theme.RemindTheme +import kotlinx.coroutines.flow.collectLatest +import java.time.LocalDate @Composable -fun WritingMoodStep3Screen() { +fun WritingMoodStep3Screen(navController: NavHostController, viewModel: WritingViewModel) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val effectFlow = viewModel.effect + val context = LocalContext.current + LaunchedEffect(true) { + effectFlow.collectLatest { effect -> + when(effect) { + is WritingContract.Effect.NavigateTo -> { + navController.navigate(effect.destinaton, effect.navOptions) + } + is WritingContract.Effect.Toastmessage -> { + Toast.makeText(context, effect.message, Toast.LENGTH_SHORT).show() + } + else -> {} + } + } + } + val year = LocalDate.now().year + val month = LocalDate.now().monthValue + val date = LocalDate.now().dayOfMonth + val dateValue = "${year}-${month}-${date}" + val textState = remember { mutableStateOf("") } + val handleTextChange = { newText: String -> + textState.value = newText + } + RemindTheme { + Column ( + modifier = Modifier + .fillMaxSize() + .background(color = RemindTheme.colors.white) + .padding( + start = 20.dp, + end = 20.dp + ) + ) { + Spacer(modifier = Modifier.height(24.dp)) + IconButton( + onClick = { + viewModel.setEvent(WritingContract.Event.PreviousButtonClicked( + Screens.Patience.Home.WritingMoodStep1.route, + Screens.Patience.Home.WritingMoodStep2.route + )) + } + ) { + Icon( + painter = painterResource(id = R.drawable.ic_arrowleft), + contentDescription = null, + tint = RemindTheme.colors.icon + ) + } + StepContainer3(modifier = Modifier.padding(top = 31.dp)) + Text( + modifier = Modifier.padding(top = 16.dp), + text = stringResource(id = R.string.오늘_하루_감사한점_3가지), + style = RemindTheme.typography.h1Bold.copy(color = RemindTheme.colors.text) + ) + Text( + modifier = Modifier.padding(top = 12.dp), + text = stringResource(id = R.string.간단한_일기를_써도_좋아요), + style = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.slate_400) + ) + Spacer(modifier = Modifier.weight(1f)) + RemindTextField( + modifier = Modifier + .fillMaxWidth() + .height(170.dp), + onTextChanged = handleTextChange, + text = textState.value, + roundedShape = 18.dp, + hintText = stringResource(id = R.string.일기_예시), + topPadding = 21.dp, + bottomPadding = 86.dp + ) + Spacer(modifier = Modifier.weight(1f)) + BasicButton( + modifier = Modifier + .fillMaxWidth(), + text = stringResource(id = R.string.다음), + RoundedCorner = 12.dp, + backgroundColor = if(textState.value != null) RemindTheme.colors.slate_100 else RemindTheme.colors.main_6, + textColor = if(textState.value != null) RemindTheme.colors.white else RemindTheme.colors.slate_300, + verticalPadding = 13.dp, + onClick = { + viewModel.setEvent(WritingContract.Event.SendInfoButton( + destinationRoute = Screens.Patience.Home.SplashCheering.route, + currentRoute = Screens.Patience.Home.WritingMoodStep3.route, + localDate = dateValue, + detail = textState.value + )) + }, + textStyle = RemindTheme.typography.b2Bold + ) + } + } +} +@Preview +@Composable +fun StepContainer3( + modifier: Modifier = Modifier +) { + Row( + modifier = modifier + ) { + StepComponent(text = 1, backgroundColor = RemindTheme.colors.main_6, textColor = RemindTheme.colors.slate_50) + Spacer(modifier = modifier.width(6.dp)) + StepComponent(text = 2, backgroundColor = RemindTheme.colors.main_6, textColor = RemindTheme.colors.slate_50) + Spacer(modifier = modifier.width(6.dp)) + StepComponent(text = 3, backgroundColor = RemindTheme.colors.main_6, textColor = RemindTheme.colors.slate_50) + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt index dd02e23..fec7e03 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt @@ -1,58 +1,133 @@ package com.example.remind.feature.screens.patience.writing +import androidx.lifecycle.viewModelScope import androidx.navigation.navOptions import com.example.remind.app.Screens import com.example.remind.core.base.BaseViewModel +import com.example.remind.data.model.request.MoodActivity +import com.example.remind.data.model.request.WritingMoodRequest +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.domain.usecase.patience_usecase.GetActivityUseCase +import com.example.remind.domain.usecase.patience_usecase.SetTodayMoodUseCase +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch import javax.inject.Inject - +@HiltViewModel class WritingViewModel @Inject constructor( - + private val getActivityUseCase: GetActivityUseCase, + private val setTodayMoodUseCase: SetTodayMoodUseCase ): BaseViewModel( initialState = WritingContract.State() ) { + init { + getActivityList() + + } override fun reduceState(event: WritingContract.Event) { when(event) { is WritingContract.Event.FeelingButtonClicked -> { - updateState(currentState.copy(selectFeelingType = event.feelingType)) + updateState(currentState.copy(totalFeelingType = event.feelingType)) } is WritingContract.Event.NextButtonClicked -> { - navigateToRoute(event.destinationRoute, event.currentRoute) + navigateToRoute(event.destinationRoute, event.currentRoute, false) } is WritingContract.Event.NavigateToHome -> { - navigateToHome() + navigateToRoute(Screens.Patience.Home.route, Screens.Patience.Home.WritingMoodStep1.route, true) } is WritingContract.Event.PreviousButtonClicked -> { - navigateToRoute(event.destinationRoute, event.currentRoute) + navigateToRoute(event.destinationRoute, event.currentRoute, true) + } + is WritingContract.Event.ActivityButtonClicked -> { + updateState(currentState.copy(activityId = event.activityId)) + updateState(currentState.copy(activityName = event.activityName)) + } +// + is WritingContract.Event.FeelingActivityButtonClicked -> { + updateState(currentState.copy(feelingType = event.feelingType)) + } + is WritingContract.Event.StoreFeelingListItem -> { + val newList = currentState.MoodActivityList + MoodActivity( + event.activityData.activityId, + event.activityData.detail, + event.activityData.feelingType + ) + navigateToRoute(event.destinationRoute, event.currentRoute, false) + } + is WritingContract.Event.NavigateToStep2 -> { + navigateToRoute(event.destinationRoute, event.currentRoute, true) + } + is WritingContract.Event.SendInfoButton -> { + setMoodData( + WritingMoodRequest( + detail = event.detail, + feelingType = currentState.totalFeelingType, + localDate = event.localDate, + moodActivities = currentState.MoodActivityList + ) + ) + navigateToRoute(event.destinationRoute, event.currentRoute,true) } } } - fun navigateToRoute(destination: String, current: String) { + fun navigateToRoute(destination: String, current: String, inclusiveData: Boolean) { postEffect( WritingContract.Effect.NavigateTo( destinaton = destination, navOptions = navOptions { popUpTo(current) { - inclusive = false + inclusive = inclusiveData } } ) ) } - fun navigateToHome() { - postEffect( - WritingContract.Effect.NavigateTo( - destinaton = Screens.Patience.Home.route, - navOptions = navOptions { - popUpTo(Screens.Patience.Home.WritingMoodStep1.route) { - inclusive = true - } + private fun getActivityList() { + viewModelScope.launch { + val result = getActivityUseCase.invoke() + when(result) { + is ApiResult.Success -> { + updateState(currentState.copy(ActivityList = result.data.data.activities)) } - ) - ) + is ApiResult.Failure.UnknownApiError -> { + setToastMessage("리마인드 고객센터에 문의하세요") + } + is ApiResult.Failure.NetworkError -> { + setToastMessage("네트워크 설정을 확인해주세요") + } + is ApiResult.Failure.HttpError -> { + setToastMessage("api 응답에러 ${result.code}") + } + } + } + } + + private fun setMoodData(body: WritingMoodRequest) { + viewModelScope.launch { + val result = setTodayMoodUseCase.invoke(body) + when(result) { + is ApiResult.Success -> { + + } + is ApiResult.Failure.UnknownApiError -> { + setToastMessage("리마인드 고객센터에 문의하세요") + } + is ApiResult.Failure.NetworkError -> { + setToastMessage("네트워크 설정을 확인해주세요") + } + is ApiResult.Failure.HttpError -> { + setToastMessage("api 응답에러 ${result.code}") + } + } + } + } + + fun setToastMessage(text: String) { + postEffect(WritingContract.Effect.Toastmessage(text)) } + } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_plus.xml b/app/src/main/res/drawable/ic_plus.xml new file mode 100644 index 0000000..6aeeb2e --- /dev/null +++ b/app/src/main/res/drawable/ic_plus.xml @@ -0,0 +1,16 @@ + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2ed5b09..e8df705 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,6 +33,9 @@ 다른 약물을 복용했어요! 부작용이 의심돼요! 완료 + 해당 활동이 어떤 영향을 주었나요? + 활동을 할 때 느낀 것을 간단하게 남겨볼까요? + 알림 추가 오늘하루,\n어떤 기분을 느끼셨나요? 오늘 하루의 전반적인 기분을 선택해주세요! @@ -72,12 +75,18 @@ 추가하기 환자 관리 번호를 입력해주세요. - + 요일 + 오늘의 활동은 최대 3개까지 등록 가능해요! + 활동 추가하기 삭제하기 환자 추가하기 담당 환자 추가시 코드 번호를 공유하세요! 추가 요청 수락 + Ex) 오랜만에 활기찬 기분을 느꼈다. + 오늘 하루,\n감사한 점 3가지를\n기록해 볼까요? + 간단한 일기를 써도 좋아요:) + 1.아름다운 벚꽃을 볼 수 있음에 감사해요.\n2.오늘 맛있는 빵을 먹어 감사해요.\n3.운동 할 수 있는 건강한 몸이 있음에 감사해요. 주의관리 필요 환자 대처하기 From bc6c0df0569af2e28bbb04195329aa8fdb83ed3f Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Tue, 21 May 2024 13:17:07 +0900 Subject: [PATCH 08/19] =?UTF-8?q?[feat]=20=EB=AC=B4=EB=93=9C=EC=B0=A8?= =?UTF-8?q?=ED=8A=B8=20api=EC=97=B0=EA=B2=B0=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/common/component/MedicineItem.kt | 38 ++++--- .../response/GetFeelingActivityResponse.kt | 12 +++ .../response/GetFeelingPercentResponse.kt | 11 +++ .../data/network/service/PatientService.kt | 10 ++ .../data/repository/CalendarDataSource.kt | 11 +++ .../feature/screens/patience/PatienceGraph.kt | 5 +- .../screens/patience/home/HomeScreen.kt | 16 +-- .../patience/moodchart/MoodChartContract.kt | 33 +++++++ .../{ => moodchart}/MoodChartScreen.kt | 98 ++++++++++++++----- .../patience/moodchart/MoodChartViewModel.kt | 73 ++++++++++++++ .../main/res/drawable/ic_arrow_graph_left.xml | 9 ++ .../res/drawable/ic_arrow_graph_right.xml | 9 ++ 12 files changed, 272 insertions(+), 53 deletions(-) create mode 100644 app/src/main/java/com/example/remind/data/model/response/GetFeelingActivityResponse.kt create mode 100644 app/src/main/java/com/example/remind/data/model/response/GetFeelingPercentResponse.kt create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt rename app/src/main/java/com/example/remind/feature/screens/patience/{ => moodchart}/MoodChartScreen.kt (67%) create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt create mode 100644 app/src/main/res/drawable/ic_arrow_graph_left.xml create mode 100644 app/src/main/res/drawable/ic_arrow_graph_right.xml diff --git a/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt b/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt index 0180c63..f66f0db 100644 --- a/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt +++ b/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt @@ -38,18 +38,22 @@ fun MedicineItem( ) { Box( modifier = modifier + .fillMaxWidth() .background(color = RemindTheme.colors.slate_50, shape = RoundedCornerShape(12.dp)) ) { Column( horizontalAlignment = Alignment.Start, + modifier = Modifier.fillMaxWidth() ) { Text( - modifier = modifier.padding(start = 12.dp, top = 7.dp), + modifier = Modifier.padding(start = 12.dp, top = 7.dp), text = time, style = RemindTheme.typography.b3Bold.copy(color = RemindTheme.colors.slate_600) ) Row( - modifier = modifier.padding( + modifier = Modifier + .fillMaxWidth() + .padding( start = 12.dp, end = 12.dp, top = 2.dp, @@ -60,23 +64,25 @@ fun MedicineItem( text = stringResource(id = R.string.중요도), style = RemindTheme.typography.c3Medium.copy(color = RemindTheme.colors.slate_400) ) - Spacer(modifier = modifier.width(6.dp)) + Spacer(modifier = Modifier.width(6.dp)) StarRatingBar( rating = score, onRatingChanged = {} ) } - Spacer(modifier = modifier.height(4.dp)) - if(isTaking == false) { - Row() { + Spacer(modifier = Modifier.height(4.dp)) + if(!isTaking) { + Row( + modifier = Modifier.fillMaxWidth() + ) { Text( - modifier = modifier + modifier = Modifier .weight(0.5f) .background( color = RemindTheme.colors.main_6, shape = RoundedCornerShape(bottomStart = 12.dp) ) - .clickable { doseClick }, + .clickable { doseClick() }, text = stringResource(id = R.string.복용), textAlign= TextAlign.Center, style = RemindTheme.typography.c1Bold.copy( @@ -84,15 +90,15 @@ fun MedicineItem( lineHeight = 20.sp ) ) - Spacer(modifier = modifier.width(2.dp)) + Spacer(modifier = Modifier.width(2.dp)) Text( - modifier = modifier - .fillMaxWidth() + modifier = Modifier + .weight(0.5f) .background( color = RemindTheme.colors.main_5, shape = RoundedCornerShape(bottomEnd = 12.dp) ) - .clickable { unadministeredClick }, + .clickable { unadministeredClick() }, text = stringResource(id = R.string.미복용), textAlign= TextAlign.Center, style = RemindTheme.typography.c1Bold.copy( @@ -103,13 +109,13 @@ fun MedicineItem( } } else { Text( - modifier = modifier + modifier = Modifier .fillMaxWidth() .background( color = RemindTheme.colors.slate_500, - shape = RoundedCornerShape(bottomStart = 12.dp) + shape = RoundedCornerShape(bottomStart = 12.dp, bottomEnd = 12.dp) ) - .clickable { doseClick }, + .clickable { doseClick() }, text = if(notTakingReason != "") "미복용" else isTakingTime, textAlign= TextAlign.Center, style = RemindTheme.typography.c1Bold.copy( @@ -125,5 +131,5 @@ fun MedicineItem( @Preview @Composable fun ItemPreview() { - MedicineItem(time = "아침", score= 2.0f, doseClick = {}, unadministeredClick = {}, isTaking = true, isTakingTime = "오전 7:00", notTakingReason = "미복용") + MedicineItem(time = "아침", score= 2.0f, doseClick = {}, unadministeredClick = {}, isTaking = false, isTakingTime = "오전 7:00", notTakingReason = "미복용") } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/GetFeelingActivityResponse.kt b/app/src/main/java/com/example/remind/data/model/response/GetFeelingActivityResponse.kt new file mode 100644 index 0000000..16b2bbf --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/GetFeelingActivityResponse.kt @@ -0,0 +1,12 @@ +package com.example.remind.data.model.response + +data class GetFeelingActivityResponse( + val code: Int, + val `data`: List, + val message: String +) +data class FeelingActivity( + val iconImage: String, + val name: String, + val percent: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/GetFeelingPercentResponse.kt b/app/src/main/java/com/example/remind/data/model/response/GetFeelingPercentResponse.kt new file mode 100644 index 0000000..fc0fa76 --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/GetFeelingPercentResponse.kt @@ -0,0 +1,11 @@ +package com.example.remind.data.model.response + +data class GetFeelingPercentResponse( + val code: Int, + val `data`: List, + val message: String +) +data class PercentList( + val feelingType: String, + val percent: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt index d348959..67b6e5d 100644 --- a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt +++ b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt @@ -3,6 +3,8 @@ package com.example.remind.data.network.service import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.model.request.WritingMoodRequest import com.example.remind.data.model.response.ActivityListResponse +import com.example.remind.data.model.response.GetFeelingActivityResponse +import com.example.remind.data.model.response.GetFeelingPercentResponse import com.example.remind.data.model.response.MedicineInfoResponse import com.example.remind.data.model.response.MedicingDailyInfoResponse import com.example.remind.data.model.response.MoodChartResponse @@ -48,4 +50,12 @@ interface PatientService { @Query("day") day: Int, @Query("size") size: Int, ): ApiResult + + @GET("/mood/chart/percents") + suspend fun getFeelingPercentChart(): ApiResult + + @GET("/mood/chart/percent/activity") + suspend fun getFeelingPercentChart( + @Query("feelingType") feelingType:String + ): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/CalendarDataSource.kt b/app/src/main/java/com/example/remind/data/repository/CalendarDataSource.kt index d29755c..2f3b601 100644 --- a/app/src/main/java/com/example/remind/data/repository/CalendarDataSource.kt +++ b/app/src/main/java/com/example/remind/data/repository/CalendarDataSource.kt @@ -42,6 +42,12 @@ class CalendarDataSource { val year = date.year return "${year}년 ${month}월 ${weekOfYear}주차" } + fun getWeeklyGraph(date: LocalDate): String { + val weekFields = WeekFields.of(Locale.getDefault()) + val weekOfYear = date.get(weekFields.weekOfMonth()) + val month = date.monthValue + return "${month}월 ${weekOfYear}주차" + } fun getDayForSearch(date: LocalDate): String { val year = date.year @@ -49,6 +55,11 @@ class CalendarDataSource { val date = date.dayOfMonth return "${year}.${month}.${date}" } + fun getDayForSearchChange(date: String): String { + val year = LocalDate.now().year + val month = LocalDate.now().monthValue + return "${year}.${month}.${date}" + } private fun toUiModel( dateList: List, diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt b/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt index a1a03e3..26c5722 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt @@ -14,6 +14,8 @@ import com.example.remind.feature.screens.patience.home.HomeCheeringScreen import com.example.remind.feature.screens.patience.home.HomeScreen import com.example.remind.feature.screens.patience.home.HomeViewModel import com.example.remind.feature.screens.patience.medicine.MedicineScreen +import com.example.remind.feature.screens.patience.moodchart.MoodChartScreen +import com.example.remind.feature.screens.patience.moodchart.MoodChartViewModel import com.example.remind.feature.screens.patience.writing.WritingMoodStep1Screen import com.example.remind.feature.screens.patience.writing.WritingMoodStep2FeelingScreen import com.example.remind.feature.screens.patience.writing.WritingMoodStep2LastScreen @@ -29,6 +31,7 @@ fun PatienceGraph( ) { val HomeviewModel: HomeViewModel = hiltViewModel() val WritingviewModel: WritingViewModel = hiltViewModel() + val MoodChartViewModel: MoodChartViewModel = hiltViewModel() NavHost( navController = navController, route = Screens.Patience.route, @@ -56,7 +59,7 @@ fun PatienceGraph( HomeCheeringScreen(navController) } composable(route = Screens.Patience.MoodChart.route) { - MoodChartScreen() + MoodChartScreen(navController, MoodChartViewModel) } composable(route = Screens.Patience.Medicine.route) { MedicineScreen() diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt index c057dcf..b66c180 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt @@ -82,9 +82,6 @@ fun HomeScreen(navController: NavHostController) { } } ) -// var year = LocalDate.now().year -// var month = LocalDate.now().monthValue -// var day = LocalDate.now().dayOfMonth var sendDate: String = "" var medicineTime: String = "" val dataSource = CalendarDataSource() @@ -216,6 +213,9 @@ fun HomeScreen(navController: NavHostController) { else -> "저녁" } MedicineItem( + modifier = Modifier + .fillMaxWidth() + .padding(end = 7.dp), time = timeText, score = item.importance.toFloat(), doseClick = { @@ -477,13 +477,3 @@ fun ShowCurrentWeek():String { } - - - -@RequiresApi(Build.VERSION_CODES.O) -@Preview -@Composable -fun HomePreview() { - EmptyTodayMoodContainer(clickToWrite = {}) -} - diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt new file mode 100644 index 0000000..0e84179 --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt @@ -0,0 +1,33 @@ +package com.example.remind.feature.screens.patience.moodchart + +import androidx.navigation.NavOptions +import androidx.navigation.NavOptionsBuilder +import com.example.remind.core.base.UiEffect +import com.example.remind.core.base.UiEvent +import com.example.remind.core.base.UiState +import com.example.remind.data.model.response.Mood +import com.example.remind.data.model.response.MoodChartResponse +import com.example.remind.feature.screens.patience.home.HomeContract + +class MoodChartContract { + data class State( + val moodChartData: Mood = Mood(true, emptyList()), + val xAxisData: List = emptyList(), + val date: String = "" + ): UiState + + sealed class Event: UiEvent { + data class LoadingNextData(val year: Int, val month: Int, val day: Int, val size: Int):Event() + data class LoadingPreviousData(val year: Int, val month: Int, val day: Int):Event() + data class storeDate(val date: String):Event() + } + + sealed class Effect: UiEffect { + data class NavigateTo( + val destinaton: String, + val navOptions: NavOptions? = null, + val builder: NavOptionsBuilder.() -> Unit = {} + ): MoodChartContract.Effect() + data class Toastmessage(val message: String): MoodChartContract.Effect() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/MoodChartScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt similarity index 67% rename from app/src/main/java/com/example/remind/feature/screens/patience/MoodChartScreen.kt rename to app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt index 6d6b075..ba5d32e 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/MoodChartScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt @@ -1,12 +1,15 @@ -package com.example.remind.feature.screens.patience +package com.example.remind.feature.screens.patience.moodchart 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.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -17,6 +20,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll 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.graphics.Brush @@ -25,6 +29,8 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavHostController import com.example.remind.R import com.example.remind.core.common.component.BasicButton import com.example.remind.core.common.component.BasicTextButton @@ -39,9 +45,10 @@ import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphStyle import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphVisibility import com.jaikeerthick.composable_graphs.style.LabelPosition import java.time.LocalDate - @Composable -fun MoodChartScreen() { +fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewModel) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val effectFlow = viewModel.effect val scrollState = rememberScrollState() val graphYaxisList = listOf( graphScoreModel(100, R.drawable.ic_verygood), @@ -53,6 +60,8 @@ fun MoodChartScreen() { RemindTheme { Column( modifier = Modifier + .fillMaxSize() + .background(color = RemindTheme.colors.white) .padding(horizontal = 20.dp) .verticalScroll(scrollState) ) { @@ -79,7 +88,7 @@ fun MoodChartScreen() { Spacer(modifier = Modifier.height(8.dp)) BasicButton( modifier = Modifier.fillMaxWidth(), - text = "${showSelectDate()} 기록 확인", + text = if(uiState.date == "") "${showSelectDate()} 기록 확인" else "${showChangeDate(uiState.date)} 기록 확인", RoundedCorner = 12.dp, backgroundColor = RemindTheme.colors.main_6, textColor = RemindTheme.colors.white, @@ -91,28 +100,62 @@ fun MoodChartScreen() { Box( modifier = Modifier .fillMaxWidth() + .height(300.dp) .border( width = 1.dp, shape = RoundedCornerShape(12.dp), color = RemindTheme.colors.grayscale_2 ) ) { + Row( + modifier = Modifier + .align(Alignment.TopCenter) + .padding(top = 10.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Image( + modifier = Modifier.padding(end = 7.dp), + painter = painterResource(id = R.drawable.ic_arrow_graph_left), + contentDescription = null + ) + Text( + modifier = Modifier.padding(end = 7.dp), + text = ShowWeek(), + style = RemindTheme.typography.b3Medium.copy(color = RemindTheme.colors.text) + ) + Image( + painter = painterResource(id = R.drawable.ic_arrow_graph_right), + contentDescription = null + ) + } Row( modifier = Modifier .fillMaxWidth() - .align(Alignment.Center) .padding(start = 7.dp, end = 10.dp) ) { Column( - modifier = Modifier, + modifier = Modifier + .fillMaxHeight() + .padding(top = 20.dp), verticalArrangement = Arrangement.SpaceEvenly ) { - for(i in 0..4) { - ScoreList(data = graphYaxisList.get(i)) + graphYaxisList.forEach { data -> + ScoreList( + data = data, + modifier = Modifier.weight(1f) + ) } } Spacer(modifier = Modifier.width(25.dp)) - GraphComponent() + if(uiState.xAxisData.isNotEmpty()) { + GraphComponent( + modifier = Modifier.weight(4f), + dateList = uiState.xAxisData, + pointClick = {clickedDate-> + viewModel.setEvent(MoodChartContract.Event.storeDate(clickedDate)) + } + ) + } } } Text( @@ -129,14 +172,14 @@ fun MoodChartScreen() { } } - -//api연결후 수정 필요함 @Composable fun GraphComponent( - modifier: Modifier = Modifier + modifier: Modifier = Modifier, + dateList: List, + pointClick: (String) -> Unit ){ - val xAxisData = listOf("Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat") - val yAxisData = listOf(100, 75, 100, 25, 75, 50, 50) + val xAxisData = dateList + val yAxisData = listOf(100, 83, 66, 49, 35,18,0) val dataModel = mutableListOf() for(i in xAxisData.indices) { val lineData = LineData(xAxisData[i], yAxisData[i]) @@ -162,9 +205,12 @@ fun GraphComponent( yAxisLabelPosition = LabelPosition.LEFT ) LineGraph( + modifier = Modifier.padding(top = 17.dp), data = dataModel, style = style, - onPointClick = {} + onPointClick = { lineData-> + pointClick(lineData.x) + } ) } @@ -176,14 +222,15 @@ fun ScoreList( data: graphScoreModel ) { Column( + modifier = modifier.fillMaxHeight(), horizontalAlignment = Alignment.CenterHorizontally ) { Image( - modifier = modifier.size(15.dp, 15.dp), + modifier = Modifier.size(15.dp, 15.dp), painter = painterResource(id = data.img), contentDescription = null ) - Spacer(modifier = modifier.height(1.dp)) + Spacer(modifier = Modifier.height(1.dp)) Text( text = data.score.toString(), style = RemindTheme.typography.c2Medium.copy(color = RemindTheme.colors.text) @@ -191,15 +238,20 @@ fun ScoreList( } } +fun ShowWeek(): String { + val dataSoruce = CalendarDataSource() + val result = dataSoruce.getWeeklyGraph(LocalDate.now()) + return result +} + fun showSelectDate(): String { val dataSource = CalendarDataSource() val result = dataSource.getDayForSearch(LocalDate.now()) return result } - - -@Preview -@Composable -fun ChartPreview() { - +fun showChangeDate(date: String): String { + val dataSource = CalendarDataSource() + val result = dataSource.getDayForSearchChange(date) + return result } + diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt new file mode 100644 index 0000000..1f19120 --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt @@ -0,0 +1,73 @@ +package com.example.remind.feature.screens.patience.moodchart + +import androidx.lifecycle.viewModelScope +import com.example.remind.core.base.BaseViewModel +import com.example.remind.data.model.response.MoodChartDto +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.domain.usecase.patience_usecase.GetMoodChartUseCase +import com.example.remind.feature.screens.patience.home.HomeContract +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import java.time.LocalDate +import javax.inject.Inject + +@HiltViewModel +class MoodChartViewModel @Inject constructor( + private val getMoodChartUseCase: GetMoodChartUseCase +): BaseViewModel( + initialState = MoodChartContract.State() +) { + val year = LocalDate.now().year + val month = LocalDate.now().monthValue + val date = LocalDate.now().dayOfMonth + init { + viewModelScope.launch { + getMoodChartData(year, month, date-3) + extractList() + } + } + override fun reduceState(event: MoodChartContract.Event) { + when(event) { + is MoodChartContract.Event.LoadingNextData -> { + getMoodChartData(event.year, event.month, event.day) + } + is MoodChartContract.Event.storeDate -> { + updateState(currentState.copy(date = event.date)) + } + else ->{} + } + } + + private fun getMoodChartData(year: Int, month: Int, day: Int) { + viewModelScope.launch { + val result = getMoodChartUseCase.invoke(year, month, day, 7) + when(result) { + is ApiResult.Success -> { + updateState(currentState.copy( + moodChartData = result.data.data + )) + } + else -> {} + } + } + } + fun extractList() { + val size = uiState.value.moodChartData.moodChartDtos.size + val list: MutableList = mutableListOf() + for(i in 0..size-1) { + val data = formattingDate(uiState.value.moodChartData.moodChartDtos.get(i).localDate) + list.add("${data}일") + } + updateState(currentState.copy(xAxisData = list)) + } + fun formattingDate(dateString: String):Int { + val extractString = dateString.takeLast(2) + val date: Int = extractString.toInt() + return date + } + + + fun setToastMessage(text: String) { + postEffect(MoodChartContract.Effect.Toastmessage(text)) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_graph_left.xml b/app/src/main/res/drawable/ic_arrow_graph_left.xml new file mode 100644 index 0000000..08e9c83 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_graph_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_graph_right.xml b/app/src/main/res/drawable/ic_arrow_graph_right.xml new file mode 100644 index 0000000..f553190 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_graph_right.xml @@ -0,0 +1,9 @@ + + + From 2291eb345014919d4f397b39079143cb2b9a2640 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Tue, 21 May 2024 13:27:41 +0900 Subject: [PATCH 09/19] =?UTF-8?q?[feat]=20=ED=99=9C=EB=8F=99=20=ED=8D=BC?= =?UTF-8?q?=EC=84=BC=ED=8A=B8=20api=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/network/service/PatientService.kt | 2 +- .../patient/PatientMoodChartRepository.kt | 11 +++++++++++ .../patient/PatientMoodChartRepositoryImpl.kt | 19 +++++++++++++++++++ .../GetFeelingActivityUseCase.kt | 14 ++++++++++++++ .../GetFeelingPercentUseCase.kt | 14 ++++++++++++++ .../patience/moodchart/MoodChartViewModel.kt | 6 +++++- 6 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt create mode 100644 app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetFeelingActivityUseCase.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetFeelingPercentUseCase.kt diff --git a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt index 67b6e5d..b26bba9 100644 --- a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt +++ b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt @@ -55,7 +55,7 @@ interface PatientService { suspend fun getFeelingPercentChart(): ApiResult @GET("/mood/chart/percent/activity") - suspend fun getFeelingPercentChart( + suspend fun getFeelingTypeActivity( @Query("feelingType") feelingType:String ): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt new file mode 100644 index 0000000..cb2b8fd --- /dev/null +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt @@ -0,0 +1,11 @@ +package com.example.remind.data.repository.patient + +import com.example.remind.data.model.response.GetFeelingActivityResponse +import com.example.remind.data.model.response.GetFeelingPercentResponse +import com.example.remind.data.network.adapter.ApiResult + +interface PatientMoodChartRepository { + suspend fun getFeelingPercentChart(): ApiResult + suspend fun getFeelingTypeActivity(feelingType: String): ApiResult + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt new file mode 100644 index 0000000..ec6953f --- /dev/null +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt @@ -0,0 +1,19 @@ +package com.example.remind.data.repository.patient + +import com.example.remind.data.model.response.GetFeelingActivityResponse +import com.example.remind.data.model.response.GetFeelingPercentResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.network.service.PatientService +import javax.inject.Inject + +class PatientMoodChartRepositoryImpl @Inject constructor( + private val service: PatientService +):PatientMoodChartRepository { + override suspend fun getFeelingPercentChart(): ApiResult { + return service.getFeelingPercentChart() + } + + override suspend fun getFeelingTypeActivity(feelingType: String): ApiResult { + return service.getFeelingTypeActivity(feelingType) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetFeelingActivityUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetFeelingActivityUseCase.kt new file mode 100644 index 0000000..051cd1d --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetFeelingActivityUseCase.kt @@ -0,0 +1,14 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.response.GetFeelingActivityResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMoodChartRepository +import javax.inject.Inject + +class GetFeelingActivityUseCase @Inject constructor( + private val patientMoodChartRepository: PatientMoodChartRepository +) { + suspend operator fun invoke(feelingType: String): ApiResult { + return patientMoodChartRepository.getFeelingTypeActivity(feelingType) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetFeelingPercentUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetFeelingPercentUseCase.kt new file mode 100644 index 0000000..10873c3 --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetFeelingPercentUseCase.kt @@ -0,0 +1,14 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.response.GetFeelingPercentResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMoodChartRepository +import javax.inject.Inject + +class GetFeelingPercentUseCase @Inject constructor( + private val patientMoodChartRepository: PatientMoodChartRepository +) { + suspend operator fun invoke(): ApiResult { + return patientMoodChartRepository.getFeelingPercentChart() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt index 1f19120..1e122d5 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt @@ -4,6 +4,8 @@ import androidx.lifecycle.viewModelScope import com.example.remind.core.base.BaseViewModel import com.example.remind.data.model.response.MoodChartDto import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.domain.usecase.patience_usecase.GetFeelingActivityUseCase +import com.example.remind.domain.usecase.patience_usecase.GetFeelingPercentUseCase import com.example.remind.domain.usecase.patience_usecase.GetMoodChartUseCase import com.example.remind.feature.screens.patience.home.HomeContract import dagger.hilt.android.lifecycle.HiltViewModel @@ -13,7 +15,9 @@ import javax.inject.Inject @HiltViewModel class MoodChartViewModel @Inject constructor( - private val getMoodChartUseCase: GetMoodChartUseCase + private val getMoodChartUseCase: GetMoodChartUseCase, + private val getFeelingPercentUseCase: GetFeelingPercentUseCase, + private val getFeelingActivityUseCase: GetFeelingActivityUseCase ): BaseViewModel( initialState = MoodChartContract.State() ) { From 2871fc5cd6e09c43c345db74e612cc9373b0bff0 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Tue, 21 May 2024 15:33:22 +0900 Subject: [PATCH 10/19] =?UTF-8?q?[feat]=20basicsheet=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/common/component/BasicBottomSheet.kt | 39 +++++ .../patience/moodchart/MoodChartContract.kt | 4 +- .../patience/moodchart/MoodChartScreen.kt | 65 +++++++ .../patience/moodchart/MoodChartViewModel.kt | 14 ++ .../component/FeelingPercentGraph.kt | 161 ++++++++++++++++++ .../res/drawable/moodcontainer_example.xml | 44 +++++ app/src/main/res/values/strings.xml | 4 +- 7 files changed, 329 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/moodchart/component/FeelingPercentGraph.kt create mode 100644 app/src/main/res/drawable/moodcontainer_example.xml diff --git a/app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt b/app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt new file mode 100644 index 0000000..644bd22 --- /dev/null +++ b/app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt @@ -0,0 +1,39 @@ +package com.example.remind.core.common.component + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.SheetState +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import com.example.remind.core.designsystem.theme.RemindTheme + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun BasicBottomSheet( + modifier: Modifier = Modifier, + sheetState : SheetState = rememberModalBottomSheetState(), + onDismissRequest: () -> Unit, + sheetContent: @Composable ColumnScope.() -> Unit +) { + ModalBottomSheet( + sheetState = sheetState, + onDismissRequest = onDismissRequest, + dragHandle = null, + shape = RoundedCornerShape(topStart = 20.dp, topEnd = 20.dp), + containerColor = RemindTheme.colors.white, + scrimColor = RemindTheme.colors.black.copy(alpha = 0.4f) + ) { + Column( + modifier = Modifier + .clip(RoundedCornerShape(topStart = 20.dp, topEnd = 20.dp)) + ) { + sheetContent() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt index 0e84179..cb6c923 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt @@ -7,13 +7,15 @@ import com.example.remind.core.base.UiEvent import com.example.remind.core.base.UiState import com.example.remind.data.model.response.Mood import com.example.remind.data.model.response.MoodChartResponse +import com.example.remind.data.model.response.PercentList import com.example.remind.feature.screens.patience.home.HomeContract class MoodChartContract { data class State( val moodChartData: Mood = Mood(true, emptyList()), val xAxisData: List = emptyList(), - val date: String = "" + val date: String = "", + val feelingTotalPerCent: List = emptyList() ): UiState sealed class Event: UiEvent { diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt index ba5d32e..980699a 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt @@ -31,12 +31,16 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController +import com.bumptech.glide.integration.compose.ExperimentalGlideComposeApi +import com.bumptech.glide.integration.compose.GlideImage import com.example.remind.R import com.example.remind.core.common.component.BasicButton import com.example.remind.core.common.component.BasicTextButton import com.example.remind.core.designsystem.theme.RemindTheme import com.example.remind.data.model.graphScoreModel +import com.example.remind.data.model.response.FeelingActivity import com.example.remind.data.repository.CalendarDataSource +import com.example.remind.feature.screens.patience.moodchart.component.FeelingPercentGraph import com.jaikeerthick.composable_graphs.composables.line.LineGraph import com.jaikeerthick.composable_graphs.composables.line.model.LineData import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphColors @@ -168,6 +172,31 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod text = stringResource(id = R.string.무엇을_할_때_기분이_좋은지_확인), style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.grayscale_3) ) + Box( + modifier = Modifier + .padding(top = 8.dp) + .border( + width = 1.dp, + color = RemindTheme.colors.grayscale_2, + shape = RoundedCornerShape(12.dp) + ) + ) { + FeelingPercentGraph( + modifier = Modifier.padding(top = 12.dp, bottom = 21.dp, start = 8.dp, end = 8.dp), + percentList = uiState.feelingTotalPerCent, + onClick = {} + ) + } + //활동 리스트들 들어가야함 + Text( + modifier = Modifier.padding(top = 20.dp), + text = stringResource(id = R.string.무드_차트_월별_비교) + ) + Image( + modifier = Modifier.padding(top = 8.dp, bottom = 45.dp), + painter = painterResource(id = R.drawable.moodcontainer_example), + contentDescription = null + ) } } } @@ -238,6 +267,42 @@ fun ScoreList( } } +@OptIn(ExperimentalGlideComposeApi::class) +@Composable +fun ActivityListItem( + modifier: Modifier = Modifier, + feelingActivity: FeelingActivity, +) { + Box( + modifier = modifier + .background(color = RemindTheme.colors.main_1, shape = RoundedCornerShape(8.dp)) + ) { + Row( + modifier = modifier.padding(vertical = 7.dp, horizontal = 9.dp), + horizontalArrangement = Arrangement.Start, + verticalAlignment = Alignment.CenterVertically + ) { + GlideImage( + modifier = Modifier.size(width = 23.dp, height = 23.dp), + model = feelingActivity.iconImage, + contentDescription = null + ) + Text( + modifier = Modifier.padding(start = 10.dp), + text = feelingActivity.name, + style = RemindTheme.typography.c1Medium.copy(color = RemindTheme.colors.text) + ) + Spacer(modifier = Modifier.weight(1f)) + Text( + modifier = Modifier.padding(end = 9.dp), + text = "${feelingActivity.percent}%", + style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.text) + ) + } + } +} + + fun ShowWeek(): String { val dataSoruce = CalendarDataSource() val result = dataSoruce.getWeeklyGraph(LocalDate.now()) diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt index 1e122d5..67b4c00 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt @@ -28,6 +28,7 @@ class MoodChartViewModel @Inject constructor( viewModelScope.launch { getMoodChartData(year, month, date-3) extractList() + getFeelingPerCent() } } override fun reduceState(event: MoodChartContract.Event) { @@ -55,6 +56,19 @@ class MoodChartViewModel @Inject constructor( } } } + private fun getFeelingPerCent() { + viewModelScope.launch { + val result = getFeelingPercentUseCase.invoke() + when(result) { + is ApiResult.Success -> { + updateState(currentState.copy( + feelingTotalPerCent = result.data.data + )) + } + else ->{} + } + } + } fun extractList() { val size = uiState.value.moodChartData.moodChartDtos.size val list: MutableList = mutableListOf() diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/component/FeelingPercentGraph.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/component/FeelingPercentGraph.kt new file mode 100644 index 0000000..ef3abb4 --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/component/FeelingPercentGraph.kt @@ -0,0 +1,161 @@ +package com.example.remind.feature.screens.patience.moodchart.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +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.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.example.remind.R +import com.example.remind.core.designsystem.theme.RemindTheme +import com.example.remind.data.model.FeelingScoreModel +import com.example.remind.data.model.response.PercentList + +@Composable +fun FeelingPercentGraph( + modifier: Modifier = Modifier, + percentList: List, + onClick: () -> Unit +) { + val convertPercentList:List = percentList.map { + (it.percent.toFloat())/100.0f + } + val feelingList = listOf( + FeelingScoreModel(R.drawable.ic_verygood, "정말 좋음", "VERY_GOOD"), + FeelingScoreModel(R.drawable.ic_good, "좋음", "GOOD"), + FeelingScoreModel(R.drawable.ic_normal, "보통", "NORMAL"), + FeelingScoreModel(R.drawable.ic_bad, "나쁨", "BAD"), + FeelingScoreModel(R.drawable.ic_terrible, "끔찍함", "TERRIBLE") + ) + fun findFeelingImage(feelingType: String): Int? { + val feelingImg = feelingList.find { it.text == feelingType } + return feelingImg?.imgeRes + } + Row( + modifier = modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + Column( + verticalArrangement = Arrangement.Center + ) { + Text( + text = "${percentList.get(0).percent}%", + style = RemindTheme.typography.c2Bold.copy(color = RemindTheme.colors.main_5) + ) + Box( + modifier = Modifier + .weight(convertPercentList.get(0)) + .background(color = RemindTheme.colors.main_6, shape = RoundedCornerShape(4.dp)) + .clickable( + onClick = onClick + ), + contentAlignment = Alignment.Center + ) { + Image( + modifier = Modifier + .padding(vertical = 7.dp) + .size(width = 15.dp, height = 15.dp), + painter = painterResource(id = findFeelingImage(percentList.get(0).feelingType)!!), + contentDescription = null + ) + } + } + Column( + verticalArrangement = Arrangement.Center + ) { + Text( + text = "${percentList.get(1).percent}%", + style = RemindTheme.typography.c2Bold.copy(color = RemindTheme.colors.main_5) + ) + Box( + modifier = Modifier + .weight(convertPercentList.get(1)) + .background(color = RemindTheme.colors.grayscale_3) + .clickable( + onClick = onClick + ), + contentAlignment = Alignment.Center + ) { + Image( + modifier = Modifier + .padding(vertical = 5.dp) + .size(width = 15.dp, height = 15.dp), + painter = painterResource(id = findFeelingImage(percentList.get(1).feelingType)!!), + contentDescription = null + ) + } + } + Column( + verticalArrangement = Arrangement.Center + ) { + Text( + text = "${percentList.get(2).percent}%", + style = RemindTheme.typography.c2Bold.copy(color = RemindTheme.colors.main_5) + ) + + Box( + modifier = Modifier + .weight(convertPercentList.get(2)) + .background(color = RemindTheme.colors.grayscale_2) + .clickable ( + onClick = onClick + ), + contentAlignment = Alignment.Center + ) { + Image( + modifier = Modifier + .padding(vertical = 5.dp) + .size(width = 15.dp, height = 15.dp), + painter = painterResource(id = findFeelingImage(percentList.get(2).feelingType)!!), + contentDescription = null + ) + } + } + Box( + modifier = Modifier + .weight(convertPercentList.get(3)) + .background(color = RemindTheme.colors.grayscale_1) + .clickable( + onClick = onClick + ), + contentAlignment = Alignment.Center + ) { + Image( + modifier = Modifier + .padding(vertical = 5.dp) + .size(width = 15.dp, height = 15.dp), + painter = painterResource(id = findFeelingImage(percentList.get(3).feelingType)!!), + contentDescription = null + ) + } + Box( + modifier = Modifier + .weight(convertPercentList.get(4)) + .background(color = RemindTheme.colors.sub_gray) + .clickable( + onClick = onClick + ), + contentAlignment = Alignment.Center + ) { + Image( + modifier = Modifier + .padding(vertical = 5.dp) + .size(width = 15.dp, height = 15.dp), + painter = painterResource(id = findFeelingImage(percentList.get(4).feelingType)!!), + contentDescription = null + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/moodcontainer_example.xml b/app/src/main/res/drawable/moodcontainer_example.xml new file mode 100644 index 0000000..21921bb --- /dev/null +++ b/app/src/main/res/drawable/moodcontainer_example.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e8df705..3715fdb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -87,13 +87,15 @@ 오늘 하루,\n감사한 점 3가지를\n기록해 볼까요? 간단한 일기를 써도 좋아요:) 1.아름다운 벚꽃을 볼 수 있음에 감사해요.\n2.오늘 맛있는 빵을 먹어 감사해요.\n3.운동 할 수 있는 건강한 몸이 있음에 감사해요. - + 무드 차트 월별 비동 주의관리 필요 환자 대처하기 보호자 환자 약 복용 무드 + 활동 + 남긴 기록 의사 면허 인증 의사 면허 인증 중이에요.\n인증은 최대 24시간 이내 처리됩니다. From a562dbf2fe7e45589bbab540797228f23f8409e3 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Tue, 21 May 2024 18:33:12 +0900 Subject: [PATCH 11/19] =?UTF-8?q?[feat]=20calendar=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/model/MedicineCalendarModel.kt | 11 +++ .../medicine/component/MedicineCalendar.kt | 96 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 app/src/main/java/com/example/remind/data/model/MedicineCalendarModel.kt create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/medicine/component/MedicineCalendar.kt diff --git a/app/src/main/java/com/example/remind/data/model/MedicineCalendarModel.kt b/app/src/main/java/com/example/remind/data/model/MedicineCalendarModel.kt new file mode 100644 index 0000000..f09509a --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/MedicineCalendarModel.kt @@ -0,0 +1,11 @@ +package com.example.remind.data.model + +import java.time.LocalDate + +data class MedicineCalendarModel( + val totalDates: List +) + +data class Date( + val date: LocalDate +) diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/component/MedicineCalendar.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/component/MedicineCalendar.kt new file mode 100644 index 0000000..875f498 --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/component/MedicineCalendar.kt @@ -0,0 +1,96 @@ +package com.example.remind.feature.screens.patience.medicine.component + +import androidx.compose.foundation.background +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.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.example.remind.core.designsystem.theme.RemindTheme +import java.time.LocalDate +import java.time.YearMonth + +@Composable +fun MedicineCalendar( + modifier: Modifier = Modifier +) { + val year = LocalDate.now().year + val month = LocalDate.now().monthValue + val dayOfWeek = remember { listOf("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat") } + val firstDayOfMonth = remember { LocalDate.of(year, month, 1) } + val daysInMonth = remember { YearMonth.of(year, month).lengthOfMonth() } + val firstDayOfWeek = remember { firstDayOfMonth.dayOfWeek.value % 7 } + Column ( + modifier = modifier + .fillMaxWidth() + .padding(bottom = 9.dp), + verticalArrangement = Arrangement.Center + ) { + Row( + modifier = modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceAround + ) { + dayOfWeek.forEach {day-> + Text( + text = day, + style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.text) + ) + } + } + Column( + modifier = modifier.fillMaxWidth(), + verticalArrangement = Arrangement.Center + ) { + var dayCounter = 1 + for (week in 0..5) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceEvenly + ) { + for (day in 0..6) { + if (week == 0 && day < firstDayOfWeek || dayCounter > daysInMonth) { + Box( + modifier = Modifier + .weight(1f) + .padding(4.dp) + .height(40.dp) + ) + } else { + Box( + modifier = Modifier + .weight(1f) + .padding(13.dp) + .height(30.dp) + .background(shape = CircleShape, color = RemindTheme.colors.main_6), + contentAlignment = Alignment.Center + ) { + Text( + text = dayCounter.toString() + ) + dayCounter++ + } + } + } + } + } + } + } +} + + +@Preview(showBackground = true) +@Composable +fun CalendarPreview() { + MedicineCalendar() +} From ede7523ae671e157d21bfa3e84986fd01ff844d2 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Tue, 21 May 2024 18:33:34 +0900 Subject: [PATCH 12/19] =?UTF-8?q?[feat]=20=EC=B2=98=EB=B0=A9,=20=EB=B3=B5?= =?UTF-8?q?=EC=9A=A9=EB=A5=A0=20api=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/remind/data/di/NetworkModule.kt | 5 + .../model/response/GetMedicineRateResponse.kt | 13 ++ .../response/GetMonthlyMedicineResponse.kt | 16 ++ .../model/response/GetPrescriptionResponse.kt | 21 ++ .../data/network/service/PatientService.kt | 21 ++ .../patient/PatientMedicineRepository.kt | 5 + .../patient/PatientMedicineRepositoryImpl.kt | 18 ++ .../GetMedicineRateUseCase.kt | 14 ++ .../GetMonthlyMedicineUseCase.kt | 14 ++ .../patience_usecase/PrescriptionUseCase.kt | 14 ++ .../feature/screens/patience/PatienceGraph.kt | 4 +- .../patience/medicine/MedicineContract.kt | 29 +++ .../patience/medicine/MedicineScreen.kt | 202 +++++++++++++++++- .../patience/medicine/MedicineViewModel.kt | 61 ++++++ .../patience/moodchart/MoodChartScreen.kt | 16 ++ .../patience/moodchart/MoodChartViewModel.kt | 2 - app/src/main/res/values/strings.xml | 5 + 17 files changed, 456 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/example/remind/data/model/response/GetMedicineRateResponse.kt create mode 100644 app/src/main/java/com/example/remind/data/model/response/GetMonthlyMedicineResponse.kt create mode 100644 app/src/main/java/com/example/remind/data/model/response/GetPrescriptionResponse.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMedicineRateUseCase.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMonthlyMedicineUseCase.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/PrescriptionUseCase.kt create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt diff --git a/app/src/main/java/com/example/remind/data/di/NetworkModule.kt b/app/src/main/java/com/example/remind/data/di/NetworkModule.kt index c6029ab..9852376 100644 --- a/app/src/main/java/com/example/remind/data/di/NetworkModule.kt +++ b/app/src/main/java/com/example/remind/data/di/NetworkModule.kt @@ -12,6 +12,8 @@ import com.example.remind.data.repository.auth.TokenRepository import com.example.remind.data.repository.auth.TokenRepositoryImpl import com.example.remind.data.repository.patient.PatientMedicineRepository import com.example.remind.data.repository.patient.PatientMedicineRepositoryImpl +import com.example.remind.data.repository.patient.PatientMoodChartRepository +import com.example.remind.data.repository.patient.PatientMoodChartRepositoryImpl import dagger.Binds import dagger.Module import dagger.Provides @@ -81,6 +83,9 @@ object NetworkModule { @Singleton @Binds abstract fun providesPatientMedicineRepository(patientMedicineRepositoryImpl: PatientMedicineRepositoryImpl): PatientMedicineRepository + @Singleton + @Binds + abstract fun providesPatientMoodChartRepository(patientMoodChartRepositoryImpl: PatientMoodChartRepositoryImpl): PatientMoodChartRepository } } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/GetMedicineRateResponse.kt b/app/src/main/java/com/example/remind/data/model/response/GetMedicineRateResponse.kt new file mode 100644 index 0000000..1f506d5 --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/GetMedicineRateResponse.kt @@ -0,0 +1,13 @@ +package com.example.remind.data.model.response + +data class GetMedicineRateResponse( + val code: Int, + val `data`: Rate, + val message: String +) +data class Rate( + val breakfastRate: Int=0, + val dinnerRate: Int=0, + val lunchRate: Int=0, + val totalRate: Int=0 +) diff --git a/app/src/main/java/com/example/remind/data/model/response/GetMonthlyMedicineResponse.kt b/app/src/main/java/com/example/remind/data/model/response/GetMonthlyMedicineResponse.kt new file mode 100644 index 0000000..0136db4 --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/GetMonthlyMedicineResponse.kt @@ -0,0 +1,16 @@ +package com.example.remind.data.model.response + +data class GetMonthlyMedicineResponse( + val code: Int, + val `data`: Monthly, + val message: String +) +data class Monthly( + val monthlyTakingMedicineDtos: List +) +data class MonthlyTakingMedicineDto( + val date: String, + val needMedicine: Boolean, + val takingCount: Int, + val takingLevel: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/GetPrescriptionResponse.kt b/app/src/main/java/com/example/remind/data/model/response/GetPrescriptionResponse.kt new file mode 100644 index 0000000..cb691ed --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/GetPrescriptionResponse.kt @@ -0,0 +1,21 @@ +package com.example.remind.data.model.response + +import kotlinx.serialization.Serializable + +@Serializable +data class GetPrescriptionResponse( + val code: Int, + val `data`: Prescription, + val message: String +) +@Serializable +data class Prescription( + val breakfastImportance: Int = 0, + val dinnerImportance: Int = 0, + val isExist: Boolean = true, + val lunchImportance: Int = 0, + val memo: String = "", + val name: String = "", + val period: Int = 0, + val prescriptionDate: String = "" +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt index b26bba9..9651d2d 100644 --- a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt +++ b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt @@ -5,6 +5,8 @@ import com.example.remind.data.model.request.WritingMoodRequest import com.example.remind.data.model.response.ActivityListResponse import com.example.remind.data.model.response.GetFeelingActivityResponse import com.example.remind.data.model.response.GetFeelingPercentResponse +import com.example.remind.data.model.response.GetMedicineRateResponse +import com.example.remind.data.model.response.GetPrescriptionResponse import com.example.remind.data.model.response.MedicineInfoResponse import com.example.remind.data.model.response.MedicingDailyInfoResponse import com.example.remind.data.model.response.MoodChartResponse @@ -58,4 +60,23 @@ interface PatientService { suspend fun getFeelingTypeActivity( @Query("feelingType") feelingType:String ): ApiResult + + @GET("/prescription") + suspend fun getPrescription( + @Query("memberId") memberId: Int + ): ApiResult + + @GET("/taking-medicine/rate") + suspend fun getMedicineRate( + @Query("memberId") memberId: Int + ): ApiResult + + @GET("/taking-medicine/monthly") + suspend fun getMonthlyMedicine( + @Query("memberId") memberId: Int, + @Query("year") year: Int, + @Query("month") month: Int, + ): ApiResult + + } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt index 5a6b8ce..493bddb 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt @@ -3,6 +3,8 @@ package com.example.remind.data.repository.patient import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.model.request.WritingMoodRequest import com.example.remind.data.model.response.ActivityListResponse +import com.example.remind.data.model.response.GetMedicineRateResponse +import com.example.remind.data.model.response.GetPrescriptionResponse import com.example.remind.data.model.response.MedicingDailyInfoResponse import com.example.remind.data.model.response.MoodChartResponse import com.example.remind.data.model.response.OnBoardingResponse @@ -16,4 +18,7 @@ interface PatientMedicineRepository { suspend fun getActivityInfo(): ApiResult suspend fun setTodayMood(body: WritingMoodRequest): ApiResult suspend fun getMoodChart(year: Int, month: Int, day: Int, size: Int): ApiResult + suspend fun getPrescription(memberId: Int): ApiResult + suspend fun getMedicineRate(memberId: Int): ApiResult + suspend fun getMonthlyMedicine(memberId: Int, year: Int, month: Int,): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt index 1ae235c..6e9f7ae 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt @@ -3,6 +3,8 @@ package com.example.remind.data.repository.patient import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.model.request.WritingMoodRequest import com.example.remind.data.model.response.ActivityListResponse +import com.example.remind.data.model.response.GetMedicineRateResponse +import com.example.remind.data.model.response.GetPrescriptionResponse import com.example.remind.data.model.response.MedicingDailyInfoResponse import com.example.remind.data.model.response.MoodChartResponse import com.example.remind.data.model.response.OnBoardingResponse @@ -42,4 +44,20 @@ class PatientMedicineRepositoryImpl @Inject constructor( ): ApiResult { return service.getMoodChart(year, month, day, size) } + + override suspend fun getPrescription(memberId: Int): ApiResult { + return service.getPrescription(memberId) + } + + override suspend fun getMedicineRate(memberId: Int): ApiResult { + return service.getMedicineRate(memberId) + } + + override suspend fun getMonthlyMedicine( + memberId: Int, + year: Int, + month: Int + ): ApiResult { + return service.getMonthlyMedicine(memberId, year, month) + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMedicineRateUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMedicineRateUseCase.kt new file mode 100644 index 0000000..7873b81 --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMedicineRateUseCase.kt @@ -0,0 +1,14 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.response.GetMedicineRateResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMedicineRepository +import javax.inject.Inject + +class GetMedicineRateUseCase @Inject constructor( + private val patientMedicineRepository: PatientMedicineRepository +) { + suspend operator fun invoke(memberId: Int): ApiResult { + return patientMedicineRepository.getMedicineRate(memberId) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMonthlyMedicineUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMonthlyMedicineUseCase.kt new file mode 100644 index 0000000..8c3eeb2 --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMonthlyMedicineUseCase.kt @@ -0,0 +1,14 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.response.GetMedicineRateResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMedicineRepository +import javax.inject.Inject + +class GetMonthlyMedicineUseCase @Inject constructor( + private val patientMedicineRepository: PatientMedicineRepository +) { + suspend operator fun invoke(memberId: Int, year: Int, month: Int,): ApiResult { + return patientMedicineRepository.getMonthlyMedicine(memberId, year, month) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/PrescriptionUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/PrescriptionUseCase.kt new file mode 100644 index 0000000..963e8e3 --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/PrescriptionUseCase.kt @@ -0,0 +1,14 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.response.GetPrescriptionResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMedicineRepository +import javax.inject.Inject + +class PrescriptionUseCase @Inject constructor( + private val patientMedicineRepository: PatientMedicineRepository +) { + suspend operator fun invoke(memberId: Int): ApiResult { + return patientMedicineRepository.getPrescription(memberId) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt b/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt index 26c5722..f571466 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt @@ -14,6 +14,7 @@ import com.example.remind.feature.screens.patience.home.HomeCheeringScreen import com.example.remind.feature.screens.patience.home.HomeScreen import com.example.remind.feature.screens.patience.home.HomeViewModel import com.example.remind.feature.screens.patience.medicine.MedicineScreen +import com.example.remind.feature.screens.patience.medicine.MedicineViewModel import com.example.remind.feature.screens.patience.moodchart.MoodChartScreen import com.example.remind.feature.screens.patience.moodchart.MoodChartViewModel import com.example.remind.feature.screens.patience.writing.WritingMoodStep1Screen @@ -32,6 +33,7 @@ fun PatienceGraph( val HomeviewModel: HomeViewModel = hiltViewModel() val WritingviewModel: WritingViewModel = hiltViewModel() val MoodChartViewModel: MoodChartViewModel = hiltViewModel() + val MedicineViewModel: MedicineViewModel = hiltViewModel() NavHost( navController = navController, route = Screens.Patience.route, @@ -62,7 +64,7 @@ fun PatienceGraph( MoodChartScreen(navController, MoodChartViewModel) } composable(route = Screens.Patience.Medicine.route) { - MedicineScreen() + MedicineScreen(navController, MedicineViewModel) } composable(route = Screens.Patience.MyPage.route) { MyPageScreen() diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt new file mode 100644 index 0000000..8b3d81c --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt @@ -0,0 +1,29 @@ +package com.example.remind.feature.screens.patience.medicine + +import androidx.navigation.NavOptions +import androidx.navigation.NavOptionsBuilder +import com.example.remind.core.base.UiEffect +import com.example.remind.core.base.UiEvent +import com.example.remind.core.base.UiState +import com.example.remind.data.model.response.Prescription +import com.example.remind.data.model.response.Rate + +class MedicineContract { + data class State( + val prescription: Prescription = Prescription(), + val alarmDialogState: Boolean = false, + val rate: Rate = Rate() + ): UiState + + sealed class Event: UiEvent { + + } + sealed class Effect: UiEffect { + data class NavigateTo( + val destinaton: String, + val navOptions: NavOptions? = null, + val builder: NavOptionsBuilder.() -> Unit = {} + ): MedicineContract.Effect() + data class Toastmessage(val message: String): MedicineContract.Effect() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt index b0ed002..d4ff0c3 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt @@ -20,6 +20,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush @@ -31,9 +33,16 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavHostController import com.example.remind.R +import com.example.remind.core.common.component.BasicButton +import com.example.remind.core.common.component.StarRatingBar import com.example.remind.core.designsystem.theme.Pretendard import com.example.remind.core.designsystem.theme.RemindTheme +import com.example.remind.data.model.response.Prescription +import com.example.remind.data.model.response.Rate +import com.example.remind.feature.screens.patience.moodchart.MoodChartContract import com.jaikeerthick.composable_graphs.composables.line.LineGraph import com.jaikeerthick.composable_graphs.composables.line.model.LineData import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphColors @@ -41,10 +50,26 @@ import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphFillTy import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphStyle import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphVisibility import com.jaikeerthick.composable_graphs.style.LabelPosition +import kotlinx.coroutines.flow.collectLatest @Composable -fun MedicineScreen() { +fun MedicineScreen(navController: NavHostController, viewModel: MedicineViewModel) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val effectFlow = viewModel.effect + val scrollState = rememberScrollState() + LaunchedEffect(true) { + effectFlow.collectLatest { effect -> + when(effect) { + is MedicineContract.Effect.NavigateTo -> { + navController.navigate(effect.destinaton, effect.navOptions) + } + else-> { + } + } + } + } + RemindTheme { Column( modifier = Modifier @@ -57,6 +82,181 @@ fun MedicineScreen() { text = stringResource(id = R.string.약_복용), style = RemindTheme.typography.h2Bold.copy(color = RemindTheme.colors.text) ) + Row( + modifier = Modifier.padding(top = 34.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = "00님의 약 처방", + style = RemindTheme.typography.b2Bold.copy(color = RemindTheme.colors.text) + ) + Spacer(modifier = Modifier.weight(1f)) + Text( + text = "처방날짜 들어갈자리", + style = RemindTheme.typography.c1Medium.copy(color = RemindTheme.colors.text) + ) + Text( + modifier = Modifier.padding(start = 6.dp), + text = "(몇일분 처방)", + style = RemindTheme.typography.c1Medium.copy(color = RemindTheme.colors.grayscale_3) + ) + } + CurrentMedicineContainer( + modifier = Modifier.padding(top = 7.dp), + prescription = uiState.prescription + ) + BasicButton( + modifier = Modifier.fillMaxWidth(), + text = stringResource(id = R.string.알림_설정), + RoundedCorner = 12.dp, + backgroundColor = RemindTheme.colors.main_6, + textColor = RemindTheme.colors.white, + verticalPadding = 12.dp, + onClick = { }, + textStyle = RemindTheme.typography.b2Bold + ) + Text( + modifier = Modifier.padding(top = 30.dp), + text = stringResource(id = R.string.약_복용률), + style = RemindTheme.typography.b2Bold.copy(color = RemindTheme.colors.text) + ) + MedicineRateContainer( + modifier = Modifier.padding(top = 6.dp), + rate = uiState.rate + ) + } + } +} + +@Composable +fun CurrentMedicineContainer( + modifier: Modifier = Modifier, + prescription: Prescription +) { + Box( + modifier = modifier + .fillMaxWidth() + .border( + width = 1.dp, + color = RemindTheme.colors.slate_100, + shape = RoundedCornerShape(12.dp) + ) + ) { + Column( + modifier = modifier.padding(vertical = 20.dp) + ) { + Row( + modifier = modifier.padding(top = 14.dp), + horizontalArrangement = Arrangement.SpaceEvenly + ) { + TimeMedicineList( + time = stringResource(id = R.string.아침), + importance = prescription.breakfastImportance.toFloat() + ) + TimeMedicineList( + time = stringResource(id = R.string.점심), + importance = prescription.lunchImportance.toFloat() + ) + TimeMedicineList( + time = stringResource(id = R.string.저녁), + importance = prescription.dinnerImportance.toFloat() + ) + //바꿔야함 + TimeMedicineList( + time = stringResource(id = R.string.비상용), + importance = prescription.breakfastImportance.toFloat() + ) + } + Box( + modifier = modifier.padding(top = 20.dp, bottom = 11.dp), + ) { + Text( + modifier = modifier.padding(start = 14.dp, top = 3.dp, bottom = 3.dp), + text = prescription.memo, + style = RemindTheme.typography.c2Regular.copy(color = RemindTheme.colors.slate_700) + ) + } + } + } +} + +@Composable +fun TimeMedicineList( + modifier: Modifier = Modifier, + time: String, + importance: Float, +) { + Column( + verticalArrangement = Arrangement.Center + ) { + Text( + modifier = modifier.padding(bottom = 7.dp), + text = time, + style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.main_6) + ) + StarRatingBar( + rating = importance, + onRatingChanged = {} + ) + } +} + +@Composable +fun MedicineRateContainer( + modifier: Modifier = Modifier, + rate: Rate +) { + Box( + modifier = modifier + .fillMaxWidth() + .border(width = 1.dp, color = RemindTheme.colors.slate_100, shape = RoundedCornerShape(12.dp)) + ) { + Column( + modifier = modifier.padding(vertical = 19.dp, horizontal = 20.dp), + horizontalAlignment = Alignment.Start + ) { + Row { + Text( + text = "${rate.totalRate}%", + style = RemindTheme.typography.h1Bold.copy(color= RemindTheme.colors.main_6) + ) + Text( + modifier = modifier.padding(start = 9.dp), + text = "(종합 복용률)", + style = RemindTheme.typography.c2Medium.copy(color= RemindTheme.colors.text) + ) + } + Row( + modifier = modifier.padding(top = 9.dp, bottom = 18.dp) + ) { + Text( + text = "아침: ", + style = RemindTheme.typography.c2Medium.copy(color= RemindTheme.colors.text) + ) + Text( + modifier = modifier.padding(start = 4.dp), + text = "${rate.breakfastRate}%", + style = RemindTheme.typography.c2Medium.copy(color= RemindTheme.colors.main_6) + ) + Text( + text = "점심: ", + style = RemindTheme.typography.c2Medium.copy(color= RemindTheme.colors.text) + ) + Text( + modifier = modifier.padding(start = 4.dp), + text = "${rate.lunchRate}%", + style = RemindTheme.typography.c2Medium.copy(color= RemindTheme.colors.main_6) + ) + Text( + text = "저녁: ", + style = RemindTheme.typography.c2Medium.copy(color= RemindTheme.colors.text) + ) + Text( + modifier = modifier.padding(start = 4.dp), + text = "${rate.dinnerRate}%", + style = RemindTheme.typography.c2Medium.copy(color= RemindTheme.colors.main_6) + ) + } } } } diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt new file mode 100644 index 0000000..6188b8b --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt @@ -0,0 +1,61 @@ +package com.example.remind.feature.screens.patience.medicine + +import androidx.lifecycle.viewModelScope +import com.example.remind.core.base.BaseViewModel +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.domain.usecase.patience_usecase.GetMedicineRateUseCase +import com.example.remind.domain.usecase.patience_usecase.GetMonthlyMedicineUseCase +import com.example.remind.domain.usecase.patience_usecase.PrescriptionUseCase +import com.example.remind.feature.screens.patience.moodchart.MoodChartContract +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class MedicineViewModel @Inject constructor( + private val prescriptionUseCase: PrescriptionUseCase, + private val getMonthlyMedicineUseCase: GetMonthlyMedicineUseCase, + private val getMedicineRateUseCase: GetMedicineRateUseCase +): BaseViewModel( + initialState = MedicineContract.State() +) { + init { + viewModelScope.launch { + getPrescription() + getMedicineRate() + } + } + override fun reduceState(event: MedicineContract.Event) { +// when(event) { +// +// } + } + + private fun getPrescription() { + viewModelScope.launch { + val result = prescriptionUseCase.invoke(0) + when(result) { + is ApiResult.Success -> { + updateState(currentState.copy( + prescription = result.data.data + )) + } + else ->{} + } + } + } + private fun getMedicineRate() { + viewModelScope.launch { + val result = getMedicineRateUseCase.invoke(0) + when(result){ + is ApiResult.Success -> { + updateState(currentState.copy( + rate = result.data.data + )) + } + else ->{} + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt index 980699a..6e445b4 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt @@ -1,5 +1,7 @@ package com.example.remind.feature.screens.patience.moodchart +import android.content.Intent +import android.net.Uri import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border @@ -20,6 +22,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -40,6 +43,7 @@ import com.example.remind.core.designsystem.theme.RemindTheme import com.example.remind.data.model.graphScoreModel import com.example.remind.data.model.response.FeelingActivity import com.example.remind.data.repository.CalendarDataSource +import com.example.remind.feature.screens.patience.home.HomeContract import com.example.remind.feature.screens.patience.moodchart.component.FeelingPercentGraph import com.jaikeerthick.composable_graphs.composables.line.LineGraph import com.jaikeerthick.composable_graphs.composables.line.model.LineData @@ -48,6 +52,7 @@ import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphFillTy import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphStyle import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphVisibility import com.jaikeerthick.composable_graphs.style.LabelPosition +import kotlinx.coroutines.flow.collectLatest import java.time.LocalDate @Composable fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewModel) { @@ -61,6 +66,17 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod graphScoreModel(25, R.drawable.ic_bad), graphScoreModel(0, R.drawable.ic_terrible), ) + LaunchedEffect(true) { + effectFlow.collectLatest { effect -> + when(effect) { + is MoodChartContract.Effect.NavigateTo -> { + navController.navigate(effect.destinaton, effect.navOptions) + } + else-> { + } + } + } + } RemindTheme { Column( modifier = Modifier diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt index 67b4c00..8ed07b3 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt @@ -2,12 +2,10 @@ package com.example.remind.feature.screens.patience.moodchart import androidx.lifecycle.viewModelScope import com.example.remind.core.base.BaseViewModel -import com.example.remind.data.model.response.MoodChartDto import com.example.remind.data.network.adapter.ApiResult import com.example.remind.domain.usecase.patience_usecase.GetFeelingActivityUseCase import com.example.remind.domain.usecase.patience_usecase.GetFeelingPercentUseCase import com.example.remind.domain.usecase.patience_usecase.GetMoodChartUseCase -import com.example.remind.feature.screens.patience.home.HomeContract import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import java.time.LocalDate diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3715fdb..1887baf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -60,6 +60,7 @@ 아침 점심 저녁 + 비상용 약 복용 체크 등록된 약이 없어요! 오늘 하루 기분이 어떠셨나요? @@ -96,6 +97,10 @@ 무드 활동 남긴 기록 + 약 복용률 + 모두 복용 완료 + 부분 복용 + 의사 면허 인증 의사 면허 인증 중이에요.\n인증은 최대 24시간 이내 처리됩니다. From c5ba586a99f91e2708e40c389534eecd41d6ed04 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Tue, 21 May 2024 18:50:34 +0900 Subject: [PATCH 13/19] =?UTF-8?q?[feat]=20=EC=95=BD=20=EB=B3=B5=EC=9A=A9?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../patience/medicine/MedicineScreen.kt | 59 ++++++++++++++++++- app/src/main/res/drawable/ex_info.xml | 26 ++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/drawable/ex_info.xml diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt index d4ff0c3..a7fe9b6 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt @@ -42,6 +42,7 @@ import com.example.remind.core.designsystem.theme.Pretendard import com.example.remind.core.designsystem.theme.RemindTheme import com.example.remind.data.model.response.Prescription import com.example.remind.data.model.response.Rate +import com.example.remind.feature.screens.patience.medicine.component.MedicineCalendar import com.example.remind.feature.screens.patience.moodchart.MoodChartContract import com.jaikeerthick.composable_graphs.composables.line.LineGraph import com.jaikeerthick.composable_graphs.composables.line.model.LineData @@ -124,9 +125,61 @@ fun MedicineScreen(navController: NavHostController, viewModel: MedicineViewMode modifier = Modifier.padding(top = 6.dp), rate = uiState.rate ) + Box( + modifier = Modifier + .padding(bottom = 66.dp) + .fillMaxWidth() + .border( + width = 1.dp, + color = RemindTheme.colors.slate_100, + shape = RoundedCornerShape(12.dp) + ) + ) { + Column( + modifier = Modifier.padding(horizontal = 20.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + CalendarHeader(modifier = Modifier.padding(top = 9.dp)) + MedicineCalendar() + Image( + modifier = Modifier.padding(end = 15.dp, bottom = 24.dp), + painter = painterResource(id = R.drawable.ex_info), + contentDescription = null + ) + } + } } } } +@Preview +@Composable +fun CalendarHeader( + modifier: Modifier = Modifier, +) { + Row( + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically + ) { + Image( + modifier = modifier.size(width = 7.dp, height = 6.dp), + painter = painterResource(id = R.drawable.ic_arrow_graph_left), + contentDescription = null + ) + Text( + modifier = modifier.padding(start = 4.dp), + text = "2024년 5월", + style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.text) + ) + Image( + modifier = modifier + .padding(start = 4.dp) + .size(width = 7.dp, height = 6.dp), + painter = painterResource(id = R.drawable.ic_arrow_graph_right), + contentDescription = null + ) + } +} @Composable fun CurrentMedicineContainer( @@ -209,7 +262,11 @@ fun MedicineRateContainer( Box( modifier = modifier .fillMaxWidth() - .border(width = 1.dp, color = RemindTheme.colors.slate_100, shape = RoundedCornerShape(12.dp)) + .border( + width = 1.dp, + color = RemindTheme.colors.slate_100, + shape = RoundedCornerShape(12.dp) + ) ) { Column( modifier = modifier.padding(vertical = 19.dp, horizontal = 20.dp), diff --git a/app/src/main/res/drawable/ex_info.xml b/app/src/main/res/drawable/ex_info.xml new file mode 100644 index 0000000..92ee131 --- /dev/null +++ b/app/src/main/res/drawable/ex_info.xml @@ -0,0 +1,26 @@ + + + + + + + + From bda190b47eb0d8a8388e01d30728def4e0aa4991 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Tue, 21 May 2024 21:42:56 +0900 Subject: [PATCH 14/19] =?UTF-8?q?[feat]=20=EB=AC=B4=EB=93=9C=EC=B0=A8?= =?UTF-8?q?=ED=8A=B8=20=ED=99=94=EB=A9=B4=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/GetFeelingPercentResponse.kt | 2 +- .../patience/moodchart/MoodChartContract.kt | 1 + .../patience/moodchart/MoodChartScreen.kt | 34 +++++++++++++------ .../patience/moodchart/MoodChartViewModel.kt | 4 ++- .../component/FeelingPercentGraph.kt | 25 ++++---------- 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/example/remind/data/model/response/GetFeelingPercentResponse.kt b/app/src/main/java/com/example/remind/data/model/response/GetFeelingPercentResponse.kt index fc0fa76..e004083 100644 --- a/app/src/main/java/com/example/remind/data/model/response/GetFeelingPercentResponse.kt +++ b/app/src/main/java/com/example/remind/data/model/response/GetFeelingPercentResponse.kt @@ -7,5 +7,5 @@ data class GetFeelingPercentResponse( ) data class PercentList( val feelingType: String, - val percent: Int + val percent: Double ) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt index cb6c923..ba7c3c7 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt @@ -14,6 +14,7 @@ class MoodChartContract { data class State( val moodChartData: Mood = Mood(true, emptyList()), val xAxisData: List = emptyList(), + val yAxisData: List = emptyList(), val date: String = "", val feelingTotalPerCent: List = emptyList() ): UiState diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt index 6e445b4..d77cad4 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt @@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -28,6 +29,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -170,11 +172,14 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod if(uiState.xAxisData.isNotEmpty()) { GraphComponent( modifier = Modifier.weight(4f), - dateList = uiState.xAxisData, + dateListX = uiState.xAxisData, + dateListY = uiState.yAxisData, pointClick = {clickedDate-> viewModel.setEvent(MoodChartContract.Event.storeDate(clickedDate)) } ) + } else { + CircularProgressIndicator() } } } @@ -197,11 +202,16 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod shape = RoundedCornerShape(12.dp) ) ) { - FeelingPercentGraph( - modifier = Modifier.padding(top = 12.dp, bottom = 21.dp, start = 8.dp, end = 8.dp), - percentList = uiState.feelingTotalPerCent, - onClick = {} - ) + if(uiState.feelingTotalPerCent.isNotEmpty()) { + FeelingPercentGraph( + modifier = Modifier.padding(top = 12.dp, bottom = 21.dp, start = 8.dp, end = 8.dp), + percentList = uiState.feelingTotalPerCent, + onClick = {} + ) + } else { + CircularProgressIndicator() + } + } //활동 리스트들 들어가야함 Text( @@ -209,8 +219,11 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod text = stringResource(id = R.string.무드_차트_월별_비교) ) Image( - modifier = Modifier.padding(top = 8.dp, bottom = 45.dp), + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp, bottom = 105.dp), painter = painterResource(id = R.drawable.moodcontainer_example), + contentScale = ContentScale.FillWidth, contentDescription = null ) } @@ -220,11 +233,12 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod @Composable fun GraphComponent( modifier: Modifier = Modifier, - dateList: List, + dateListX: List, + dateListY: List, pointClick: (String) -> Unit ){ - val xAxisData = dateList - val yAxisData = listOf(100, 83, 66, 49, 35,18,0) + val xAxisData = dateListX + val yAxisData = dateListY val dataModel = mutableListOf() for(i in xAxisData.indices) { val lineData = LineData(xAxisData[i], yAxisData[i]) diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt index 8ed07b3..38ec597 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt @@ -47,7 +47,9 @@ class MoodChartViewModel @Inject constructor( when(result) { is ApiResult.Success -> { updateState(currentState.copy( - moodChartData = result.data.data + moodChartData = result.data.data, + xAxisData = result.data.data.moodChartDtos.map { it.localDate }, + yAxisData = result.data.data.moodChartDtos.map { it.score } )) } else -> {} diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/component/FeelingPercentGraph.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/component/FeelingPercentGraph.kt index ef3abb4..efd74d6 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/component/FeelingPercentGraph.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/component/FeelingPercentGraph.kt @@ -30,7 +30,7 @@ fun FeelingPercentGraph( onClick: () -> Unit ) { val convertPercentList:List = percentList.map { - (it.percent.toFloat())/100.0f + (it.percent.toInt())/100.0f } val feelingList = listOf( FeelingScoreModel(R.drawable.ic_verygood, "정말 좋음", "VERY_GOOD"), @@ -50,10 +50,6 @@ fun FeelingPercentGraph( Column( verticalArrangement = Arrangement.Center ) { - Text( - text = "${percentList.get(0).percent}%", - style = RemindTheme.typography.c2Bold.copy(color = RemindTheme.colors.main_5) - ) Box( modifier = Modifier .weight(convertPercentList.get(0)) @@ -75,10 +71,6 @@ fun FeelingPercentGraph( Column( verticalArrangement = Arrangement.Center ) { - Text( - text = "${percentList.get(1).percent}%", - style = RemindTheme.typography.c2Bold.copy(color = RemindTheme.colors.main_5) - ) Box( modifier = Modifier .weight(convertPercentList.get(1)) @@ -100,11 +92,6 @@ fun FeelingPercentGraph( Column( verticalArrangement = Arrangement.Center ) { - Text( - text = "${percentList.get(2).percent}%", - style = RemindTheme.typography.c2Bold.copy(color = RemindTheme.colors.main_5) - ) - Box( modifier = Modifier .weight(convertPercentList.get(2)) @@ -124,11 +111,11 @@ fun FeelingPercentGraph( } } Box( - modifier = Modifier - .weight(convertPercentList.get(3)) - .background(color = RemindTheme.colors.grayscale_1) - .clickable( - onClick = onClick + modifier = Modifier + .weight(convertPercentList.get(3)) + .background(color = RemindTheme.colors.grayscale_1) + .clickable( + onClick = onClick ), contentAlignment = Alignment.Center ) { From 318d018e514db11ab7cae61252a56b11f1d33319 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Tue, 21 May 2024 23:53:02 +0900 Subject: [PATCH 15/19] =?UTF-8?q?[feat]=20=EB=82=A0=EC=A7=9C=EB=B3=84=20?= =?UTF-8?q?=EB=AC=B4=EB=93=9C=EC=A0=95=EB=B3=B4=20bottomsheet=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/response/GetDailyMoodResponse.kt | 18 ++ .../data/network/service/PatientService.kt | 6 + .../patient/PatientMoodChartRepository.kt | 2 + .../patient/PatientMoodChartRepositoryImpl.kt | 5 + .../patience_usecase/GetMoodDailyUseCase.kt | 14 + .../screens/doctor/DoctorMainScreen.kt | 1 - .../moodchart/MoodChartBottomSheet.kt | 264 ++++++++++++++++++ .../patience/moodchart/MoodChartContract.kt | 8 +- .../patience/moodchart/MoodChartViewModel.kt | 32 ++- .../writing/WritingMoodStep2Screen.kt | 4 - app/src/main/res/drawable/ic_nottaking.xml | 13 + app/src/main/res/drawable/ic_taking.xml | 10 + app/src/main/res/values/strings.xml | 1 - 13 files changed, 369 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/com/example/remind/data/model/response/GetDailyMoodResponse.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMoodDailyUseCase.kt create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt create mode 100644 app/src/main/res/drawable/ic_nottaking.xml create mode 100644 app/src/main/res/drawable/ic_taking.xml diff --git a/app/src/main/java/com/example/remind/data/model/response/GetDailyMoodResponse.kt b/app/src/main/java/com/example/remind/data/model/response/GetDailyMoodResponse.kt new file mode 100644 index 0000000..b66c257 --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/GetDailyMoodResponse.kt @@ -0,0 +1,18 @@ +package com.example.remind.data.model.response + +data class GetDailyMoodResponse( + val code: Int, + val `data`: Data, + val message: String +) +data class Data( + val activities: List = emptyList(), + val feelingType: String = "", + val moodDetail: String = "" +) +data class Activities( + val detail: String = "", + val feelingType: String = "", + val iconImg: String = "", + val name: String ="" +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt index 9651d2d..d9bcb4d 100644 --- a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt +++ b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt @@ -3,6 +3,7 @@ package com.example.remind.data.network.service import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.model.request.WritingMoodRequest import com.example.remind.data.model.response.ActivityListResponse +import com.example.remind.data.model.response.GetDailyMoodResponse import com.example.remind.data.model.response.GetFeelingActivityResponse import com.example.remind.data.model.response.GetFeelingPercentResponse import com.example.remind.data.model.response.GetMedicineRateResponse @@ -78,5 +79,10 @@ interface PatientService { @Query("month") month: Int, ): ApiResult + @GET("/mood") + suspend fun getDailyMood( + @Path("moodDate") moodDate:String + ): ApiResult + } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt index cb2b8fd..92eb06d 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt @@ -1,5 +1,6 @@ package com.example.remind.data.repository.patient +import com.example.remind.data.model.response.GetDailyMoodResponse import com.example.remind.data.model.response.GetFeelingActivityResponse import com.example.remind.data.model.response.GetFeelingPercentResponse import com.example.remind.data.network.adapter.ApiResult @@ -7,5 +8,6 @@ import com.example.remind.data.network.adapter.ApiResult interface PatientMoodChartRepository { suspend fun getFeelingPercentChart(): ApiResult suspend fun getFeelingTypeActivity(feelingType: String): ApiResult + suspend fun getMoodDaily(moodDate: String): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt index ec6953f..ecf13bc 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt @@ -1,5 +1,6 @@ package com.example.remind.data.repository.patient +import com.example.remind.data.model.response.GetDailyMoodResponse import com.example.remind.data.model.response.GetFeelingActivityResponse import com.example.remind.data.model.response.GetFeelingPercentResponse import com.example.remind.data.network.adapter.ApiResult @@ -16,4 +17,8 @@ class PatientMoodChartRepositoryImpl @Inject constructor( override suspend fun getFeelingTypeActivity(feelingType: String): ApiResult { return service.getFeelingTypeActivity(feelingType) } + + override suspend fun getMoodDaily(moodDate: String): ApiResult { + return service.getDailyMood(moodDate) + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMoodDailyUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMoodDailyUseCase.kt new file mode 100644 index 0000000..a8565fc --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMoodDailyUseCase.kt @@ -0,0 +1,14 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.response.GetDailyMoodResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMoodChartRepository +import javax.inject.Inject + +class GetMoodDailyUseCase @Inject constructor( + private val patientMoodChartRepository: PatientMoodChartRepository +) { + suspend operator fun invoke(moodDate: String): ApiResult { + return patientMoodChartRepository.getMoodDaily(moodDate) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/doctor/DoctorMainScreen.kt b/app/src/main/java/com/example/remind/feature/screens/doctor/DoctorMainScreen.kt index a0a4fc9..2cc254b 100644 --- a/app/src/main/java/com/example/remind/feature/screens/doctor/DoctorMainScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/doctor/DoctorMainScreen.kt @@ -96,7 +96,6 @@ fun DoctorMain( formattedIndex = index.toString() } BasicListItem( - //modifier = Modifier.padding(start = 26.dp, end = 28.dp), modifier = Modifier, name = item.name, index = formattedIndex, diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt new file mode 100644 index 0000000..c28c599 --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt @@ -0,0 +1,264 @@ +package com.example.remind.feature.screens.patience.moodchart + +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.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Text +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +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.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.bumptech.glide.integration.compose.ExperimentalGlideComposeApi +import com.bumptech.glide.integration.compose.GlideImage +import com.example.remind.R +import com.example.remind.core.common.component.BasicBottomSheet +import com.example.remind.core.designsystem.theme.RemindTheme +import com.example.remind.data.model.FeelingScoreModel +import com.example.remind.data.model.response.Activities +import com.example.remind.data.model.response.DailyTakingMedicineList + +val feelingList = listOf( + FeelingScoreModel(R.drawable.ic_verygood, "정말 좋음", "VERY_GOOD", "기분이 정말 좋았어요!"), + FeelingScoreModel(R.drawable.ic_good, "좋음", "GOOD", "기분이 좋았어요!"), + FeelingScoreModel(R.drawable.ic_normal, "보통", "NORMAL", "기분이 보통이었어요!"), + FeelingScoreModel(R.drawable.ic_bad, "나쁨", "BAD", "기분이 나빴어요."), + FeelingScoreModel(R.drawable.ic_terrible, "끔찍함", "TERRIBLE", "기분이 매우 안좋았어요.") +) +fun findFeelingImage(feelingType: String): Int? { + val feelingImg = feelingList.find { it.text == feelingType } + return feelingImg?.imgeRes +} +fun findFeelingText(feelingType: String): String? { + val feelingText = feelingList.find { it.feeling == feelingType } + return feelingText?.feeling +} +fun findFeelingMent(feelingType: String): String? { + val feelingText = feelingList.find { it.feeling == feelingType } + return feelingText?.description +} +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MoodChartBottomSheet( + modifier: Modifier = Modifier, + viewModel: MoodChartViewModel, +) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val effectFlow = viewModel.effect + val scrollState = rememberScrollState() + BasicBottomSheet( + onDismissRequest = { } + ) { + Column( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 20.dp) + .verticalScroll(scrollState), + ) { + Row( + modifier = modifier.fillMaxWidth() + ) { + Text( + textAlign = TextAlign.Center, + text = "날짜날짜" + ) + Spacer(modifier = modifier.weight(1f)) + IconButton(onClick = {}) { + Icon( + painter = painterResource(id = R.drawable.ic_close), + contentDescription = null + ) + } + Box( + modifier = modifier + .fillMaxWidth() + .background( + color = RemindTheme.colors.main_1, + shape = RoundedCornerShape(8.dp) + ), + contentAlignment = Alignment.Center + ) { + Row( + modifier = modifier.padding(vertical = 5.dp) + ) { + Image( + modifier = modifier.padding(end = 4.dp), + painter = painterResource(id = findFeelingImage(uiState.dailyMood.feelingType)!!), + contentDescription = null + ) + Text( + text = findFeelingText(uiState.dailyMood.feelingType)!!, + style = RemindTheme.typography.h2Medium.copy(color = RemindTheme.colors.slate_800) + ) + } + Text( + modifier = modifier.padding(top = 16.dp), + text = stringResource(id = R.string.활동), + style = RemindTheme.typography.b3Medium.copy(color = RemindTheme.colors.slate_600) + ) + if(uiState.dailyMood.activities.isNotEmpty()) { + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(10.dp) + ) { + itemsIndexed(uiState.dailyMood.activities) {index, item -> + activityListItem(item = item) + } + } + } + Text( + modifier = modifier.padding(top = 16.dp), + text = stringResource(id = R.string.활동), + style = RemindTheme.typography.b3Medium.copy(color = RemindTheme.colors.slate_600) + ) + Box( + modifier = modifier + .border(width = 1.dp, color = RemindTheme.colors.grayscale_1, shape = RoundedCornerShape(8.dp)) + ) { + if(uiState.dailyMedicine.isNotEmpty()) { + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(12.dp) + ) { + itemsIndexed(uiState.dailyMedicine) {index, item -> + MedicineInfo(content = item) + } + } + } + } + } + } + } + } +} + +@OptIn(ExperimentalGlideComposeApi::class) +@Composable +fun activityListItem( + modifier: Modifier = Modifier, + item: Activities +) { + Box( + modifier = modifier + .border(width = 1.dp, color = RemindTheme.colors.grayscale_1, shape = RoundedCornerShape(8.dp)) + ) { + Column( + modifier = Modifier + .align(Alignment.TopStart) + .padding(start = 20.dp, top = 12.dp, bottom = 12.dp, end = 50.dp), + verticalArrangement = Arrangement.Center + ) { + GlideImage( + modifier = modifier.size(width = 29.dp, height = 45.dp), + model = item.iconImg, + contentDescription = null + ) + Text( + modifier = Modifier + .padding(vertical = 2.5.dp, horizontal = 20.dp) + .background( + color = RemindTheme.colors.main_2, + shape = RoundedCornerShape(18.dp) + ), + text = item.name, + style = RemindTheme.typography.c2Medium.copy(color = RemindTheme.colors.slate_600) + ) + } + Column { + Row( + modifier = modifier.padding(bottom = 6.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Image ( + modifier = Modifier + .size(width = 15.dp, height = 21.dp) + .padding(end = 3.dp), + painter = painterResource(id = findFeelingImage(item.feelingType)!!), + contentDescription = null + ) + Text ( + text = findFeelingMent(item.feelingType)!!, + style = RemindTheme.typography.b3Medium.copy(color = RemindTheme.colors.slate_600) + ) + } + Text( + text = item.detail, + style = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.slate_500) + ) + } + } +} + +@Composable +fun MedicineInfo( + modifier:Modifier = Modifier, + content: DailyTakingMedicineList +) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceEvenly + ) { + Text( + text = content.takingTime?.let { timeForamt(it) } ?: "", + style = RemindTheme.typography.b3Bold.copy(color = RemindTheme.colors.text) + ) + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + Image( + modifier = modifier.padding(end = 6.dp), + painter = if(content.isTaking == true) painterResource(id = R.drawable.ic_taking) else painterResource(id = R.drawable.ic_nottaking), + contentDescription = null + ) + if(content.isTaking == true) { + Text( + text = stringResource(id = R.string.복용), + style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.main_6) + ) + } else { + Text( + text = stringResource(id = R.string.미복용), + style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.sub_4) + ) + } + if(content.notTakingReason != null) { + Text( + modifier = modifier + .padding(horizontal = 8.dp, vertical = 2.5.dp), + text = "사유: ${content.notTakingReason}", + style = RemindTheme.typography.c3Bold.copy(color = RemindTheme.colors.slate_500) + ) + } + } + } +} + +fun timeForamt(takingTime: String): String { + when(takingTime) { + "BREAKFAST" -> return "아침" + "LUNCH" -> return "점심" + "DINNER" -> return "저녁" + else -> return "비상용" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt index ba7c3c7..2f026c4 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt @@ -5,6 +5,8 @@ import androidx.navigation.NavOptionsBuilder import com.example.remind.core.base.UiEffect import com.example.remind.core.base.UiEvent import com.example.remind.core.base.UiState +import com.example.remind.data.model.response.DailyTakingMedicineList +import com.example.remind.data.model.response.Data import com.example.remind.data.model.response.Mood import com.example.remind.data.model.response.MoodChartResponse import com.example.remind.data.model.response.PercentList @@ -16,12 +18,14 @@ class MoodChartContract { val xAxisData: List = emptyList(), val yAxisData: List = emptyList(), val date: String = "", - val feelingTotalPerCent: List = emptyList() + val dailyMood: Data = Data(), + val feelingTotalPerCent: List = emptyList(), + val dailyMedicine: List = emptyList() ): UiState sealed class Event: UiEvent { data class LoadingNextData(val year: Int, val month: Int, val day: Int, val size: Int):Event() - data class LoadingPreviousData(val year: Int, val month: Int, val day: Int):Event() + data class ClickToBottomSheet(val moodDate: String):Event() data class storeDate(val date: String):Event() } diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt index 38ec597..e59be99 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt @@ -6,6 +6,8 @@ import com.example.remind.data.network.adapter.ApiResult import com.example.remind.domain.usecase.patience_usecase.GetFeelingActivityUseCase import com.example.remind.domain.usecase.patience_usecase.GetFeelingPercentUseCase import com.example.remind.domain.usecase.patience_usecase.GetMoodChartUseCase +import com.example.remind.domain.usecase.patience_usecase.GetMoodDailyUseCase +import com.example.remind.domain.usecase.patience_usecase.PatientMedicineDailyUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import java.time.LocalDate @@ -15,7 +17,9 @@ import javax.inject.Inject class MoodChartViewModel @Inject constructor( private val getMoodChartUseCase: GetMoodChartUseCase, private val getFeelingPercentUseCase: GetFeelingPercentUseCase, - private val getFeelingActivityUseCase: GetFeelingActivityUseCase + private val getFeelingActivityUseCase: GetFeelingActivityUseCase, + private val getMoodDailyUseCase: GetMoodDailyUseCase, + private val patientMedicineDailyUseCase: PatientMedicineDailyUseCase ): BaseViewModel( initialState = MoodChartContract.State() ) { @@ -69,6 +73,32 @@ class MoodChartViewModel @Inject constructor( } } } + private fun getDailyMood(moodDate: String) { + viewModelScope.launch { + val result = getMoodDailyUseCase.invoke(moodDate) + when(result) { + is ApiResult.Success -> { + updateState(currentState.copy( + dailyMood = result.data.data + )) + } + else -> {} + } + } + } + private fun getDailyMedicine(date: String) { + viewModelScope.launch { + val result = patientMedicineDailyUseCase.invoke(0,date) + when(result) { + is ApiResult.Success -> { + updateState(currentState.copy( + dailyMedicine = result.data.data.dailyTakingMedicineDtos + )) + } + else -> {} + } + } + } fun extractList() { val size = uiState.value.moodChartData.moodChartDtos.size val list: MutableList = mutableListOf() diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt index 55d94ac..fcd6b12 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt @@ -6,7 +6,6 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box 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 @@ -41,9 +40,6 @@ import com.example.remind.app.Screens import com.example.remind.core.common.component.BasicButton import com.example.remind.core.common.component.StepComponent import com.example.remind.core.designsystem.theme.RemindTheme -import com.example.remind.data.model.request.MoodActivity -import com.example.remind.data.model.response.Activity -import com.example.remind.feature.screens.auth.login.LoginContract import kotlinx.coroutines.flow.collectLatest @Composable diff --git a/app/src/main/res/drawable/ic_nottaking.xml b/app/src/main/res/drawable/ic_nottaking.xml new file mode 100644 index 0000000..40d43c6 --- /dev/null +++ b/app/src/main/res/drawable/ic_nottaking.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/ic_taking.xml b/app/src/main/res/drawable/ic_taking.xml new file mode 100644 index 0000000..327b290 --- /dev/null +++ b/app/src/main/res/drawable/ic_taking.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1887baf..80d9348 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -101,7 +101,6 @@ 모두 복용 완료 부분 복용 - 의사 면허 인증 의사 면허 인증 중이에요.\n인증은 최대 24시간 이내 처리됩니다. 정신질환 환자 사례관리 지원 서비스 리마인드는\n보건복지부 면허인증 서비스를 통해\n면허번호 인증을 실시하고 있습니다. From 3a81a2df61363bdf4863038cf9122266aafc4983 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Wed, 22 May 2024 15:03:29 +0900 Subject: [PATCH 16/19] =?UTF-8?q?[feat]=203=EC=9E=85=EC=9E=A5=20=EC=98=A8?= =?UTF-8?q?=EB=B3=B4=EB=94=A9=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/remind/app/Screens.kt | 5 +- .../core/common/component/BasicBottomSheet.kt | 1 + .../core/common/component/RemindTextField.kt | 30 +- .../data/model/request/OnBoardingRequest.kt | 18 +- .../data/model/response/MoodChartResponse.kt | 2 +- .../remind/feature/screens/auth/AuthGraph.kt | 13 +- .../auth/onboarding/OnBoardingCheckDoctor.kt | 64 +++-- .../auth/onboarding/OnBoardingContract.kt | 12 +- .../auth/onboarding/OnBoardingFinal.kt | 19 +- .../onboarding/OnBoardingLoadingDoctor.kt | 16 +- .../auth/onboarding/OnBoardingPatience.kt | 17 +- .../onboarding/OnBoardingUserInfoScreen.kt | 259 ++++++++++++++++++ .../auth/onboarding/OnBoardingViewModel.kt | 55 +++- .../auth/onboarding/SelectTypeScreen.kt | 7 +- .../feature/screens/patience/PatienceGraph.kt | 4 + .../patience/medicine/AlarmSettingScreen.kt | 111 ++++++++ .../moodchart/MoodChartBottomSheet.kt | 25 +- .../patience/moodchart/MoodChartScreen.kt | 24 +- .../patience/moodchart/MoodChartViewModel.kt | 30 +- app/src/main/res/drawable/ic_main_logo.xml | 21 ++ 20 files changed, 613 insertions(+), 120 deletions(-) create mode 100644 app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingUserInfoScreen.kt create mode 100644 app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmSettingScreen.kt create mode 100644 app/src/main/res/drawable/ic_main_logo.xml diff --git a/app/src/main/java/com/example/remind/app/Screens.kt b/app/src/main/java/com/example/remind/app/Screens.kt index 6191f9c..51101d8 100644 --- a/app/src/main/java/com/example/remind/app/Screens.kt +++ b/app/src/main/java/com/example/remind/app/Screens.kt @@ -7,6 +7,7 @@ sealed class Screens(val route: String) { object Register: Screens("register") { object Login: Screens("login") object SelectType: Screens("selecttype") + object OnBoardingUserInfo: Screens("onboarding_userinfo") object OnBoardingPatience: Screens("patience_onboarding") object OnBoardingCheckDoctor: Screens("doctor_1") object OnBoardingLoadingDoctor: Screens("doctor_2") @@ -32,7 +33,9 @@ sealed class Screens(val route: String) { object SplashCheering: Screens("cheering") } object MoodChart: Screens("MoodChart") - object Medicine: Screens("Medicine") + object Medicine: Screens("Medicine") { + object AlarmSetting: Screens("alarm_setting") + } object MyPage: Screens("MyPage") } } diff --git a/app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt b/app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt index 644bd22..a8f2f86 100644 --- a/app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt +++ b/app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt @@ -8,6 +8,7 @@ import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.SheetState import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp diff --git a/app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt b/app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt index d16e7c0..3f923f3 100644 --- a/app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt +++ b/app/src/main/java/com/example/remind/core/common/component/RemindTextField.kt @@ -14,11 +14,14 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import com.example.remind.R import com.example.remind.core.designsystem.theme.RemindTheme @Composable @@ -29,16 +32,17 @@ fun RemindTextField( roundedShape: Dp, hintText: String, topPadding: Dp, - bottomPadding: Dp + bottomPadding: Dp, + maxLine: Int? = null ) { val interactionSource = remember { MutableInteractionSource() } val isFocused = interactionSource.collectIsFocusedAsState() val hintTextVisible by remember { - derivedStateOf { text.isEmpty() && !isFocused.value } + derivedStateOf { text.isEmpty() } } BasicTextField( value = text, - maxLines = 1, + maxLines = maxLine ?: Int.MAX_VALUE, onValueChange = onTextChanged, interactionSource = interactionSource, textStyle = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.text), @@ -60,9 +64,9 @@ fun RemindTextField( Box( modifier = modifier .fillMaxWidth() - .padding(top = topPadding, bottom = bottomPadding, start= 12.dp) + .padding(top = topPadding, bottom = bottomPadding, start = 12.dp) ) { - if(hintTextVisible) { + if(hintTextVisible && text.isEmpty()) { Text( text = hintText, style = RemindTheme.typography.c1Regular.copy(color = RemindTheme.colors.slate_400) @@ -77,5 +81,19 @@ fun RemindTextField( @Preview(showBackground = false) @Composable fun BasicTextFieldPreview() { - + val textState = remember { mutableStateOf("") } + val handleTextChange = { newText: String -> + textState.value = newText + } + RemindTextField( + modifier = Modifier + .fillMaxWidth() + .padding(start = 20.dp, end = 20.dp), + onTextChanged = handleTextChange, + text = textState.value, + roundedShape = 8.dp, + hintText = stringResource(id = R.string.번호를_입력해주세요), + topPadding = 12.dp, + bottomPadding = 50.dp + ) } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/request/OnBoardingRequest.kt b/app/src/main/java/com/example/remind/data/model/request/OnBoardingRequest.kt index b401e78..dc78344 100644 --- a/app/src/main/java/com/example/remind/data/model/request/OnBoardingRequest.kt +++ b/app/src/main/java/com/example/remind/data/model/request/OnBoardingRequest.kt @@ -4,11 +4,15 @@ import kotlinx.serialization.Serializable @Serializable data class OnBoardingRequest( - val centerName: String, - val city: String, - val district: String, - val protectorPhoneNumber: String, - val rolesType: String, - val fcmToken: String, - val doctorLicenseNumber: String + val centerName: String = "", + val city: String = "", + val district: String = "", + val protectorPhoneNumber: String = "", + val rolesType: String = "", + val fcmToken: String = "", + val doctorLicenseNumber: String = "", + val birthday: String = "", + val phoneNumber: String = "", + val gender: String = "", + val name: String = "", ) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/MoodChartResponse.kt b/app/src/main/java/com/example/remind/data/model/response/MoodChartResponse.kt index 507c4b5..eb0fb3b 100644 --- a/app/src/main/java/com/example/remind/data/model/response/MoodChartResponse.kt +++ b/app/src/main/java/com/example/remind/data/model/response/MoodChartResponse.kt @@ -12,6 +12,6 @@ data class Mood( data class MoodChartDto( val feeling: String, - val localDate: String, + val day: Int, val score: Int ) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/AuthGraph.kt b/app/src/main/java/com/example/remind/feature/screens/auth/AuthGraph.kt index 9da930e..2890f27 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/AuthGraph.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/AuthGraph.kt @@ -1,23 +1,19 @@ package com.example.remind.feature.screens.auth -import androidx.compose.runtime.Composable import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.compose.composable import androidx.navigation.navigation import com.example.remind.app.Screens -import com.example.remind.feature.screens.auth.login.LoginViewModel - -import androidx.hilt.navigation.compose.hiltViewModel import com.example.remind.feature.screens.auth.login.LoginScreen import com.example.remind.feature.screens.auth.onboarding.OnBoardingCenterScreen import com.example.remind.feature.screens.auth.onboarding.OnBoardingCheckDoctorScreen import com.example.remind.feature.screens.auth.onboarding.OnBoardingFinalScreen import com.example.remind.feature.screens.auth.onboarding.OnBoardingLoadingDoctorScreen import com.example.remind.feature.screens.auth.onboarding.OnBoardingPatienceScreen +import com.example.remind.feature.screens.auth.onboarding.OnBoardingUserInfoScreen import com.example.remind.feature.screens.auth.onboarding.OnBoardingViewModel import com.example.remind.feature.screens.auth.onboarding.SelectTypeScreen -import com.example.remind.feature.screens.patience.home.HomeViewModel fun NavGraphBuilder.RegisterGraph( navHostController: NavHostController, @@ -33,14 +29,17 @@ fun NavGraphBuilder.RegisterGraph( composable(route = Screens.Register.SelectType.route) { SelectTypeScreen(navHostController, onBoardingViewModel) } + composable(route = Screens.Register.OnBoardingUserInfo.route) { + OnBoardingUserInfoScreen(navHostController, onBoardingViewModel) + } composable(route = Screens.Register.OnBoardingPatience.route) { OnBoardingPatienceScreen(navHostController, onBoardingViewModel) } composable(route = Screens.Register.OnBoardingCheckDoctor.route) { - OnBoardingCheckDoctorScreen(navHostController) + OnBoardingCheckDoctorScreen(navHostController, onBoardingViewModel) } composable(route = Screens.Register.OnBoardingLoadingDoctor.route) { - OnBoardingLoadingDoctorScreen(navHostController) + OnBoardingLoadingDoctorScreen(navHostController, onBoardingViewModel) } composable(route = Screens.Register.OnBoardingCenter.route) { OnBoardingCenterScreen() diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingCheckDoctor.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingCheckDoctor.kt index 19f0566..9953b97 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingCheckDoctor.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingCheckDoctor.kt @@ -10,9 +10,12 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel @@ -22,16 +25,23 @@ import com.example.remind.R import com.example.remind.app.Screens import com.example.remind.core.common.component.BasicButton import com.example.remind.core.common.component.BasicOnBoardingAppBar +import com.example.remind.core.common.component.RemindTextField import com.example.remind.core.designsystem.theme.RemindTheme import com.example.remind.data.model.request.OnBoardingRequest import kotlinx.coroutines.flow.collectLatest @Composable -fun OnBoardingCheckDoctorScreen(navController: NavHostController) { - val viewModel: OnBoardingViewModel = hiltViewModel() +fun OnBoardingCheckDoctorScreen( + navController: NavHostController, + viewModel: OnBoardingViewModel +) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() val effectFlow = viewModel.effect val context = LocalContext.current + val textState = remember { mutableStateOf("") } + val handleTextChange = { newText: String -> + textState.value = newText + } LaunchedEffect(true) { effectFlow.collectLatest { effect -> when(effect) { @@ -59,7 +69,23 @@ fun OnBoardingCheckDoctorScreen(navController: NavHostController) { lineHeight = 49.sp ) ) - Spacer(modifier = Modifier.weight(1f)) + Text( + modifier = Modifier.padding(top = 66.dp), + text= "면허번호", + style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.text) + ) + RemindTextField( + modifier = Modifier + .fillMaxWidth() + .padding(start = 20.dp, end = 20.dp, top = 4.dp), + onTextChanged = handleTextChange, + text = textState.value, + roundedShape = 8.dp, + hintText = "번호를 입력해주세요.", + topPadding = 13.dp, + bottomPadding = 13.dp, + maxLine = 1 + ) BasicButton( modifier = Modifier .fillMaxWidth() @@ -70,27 +96,25 @@ fun OnBoardingCheckDoctorScreen(navController: NavHostController) { textColor = RemindTheme.colors.white, verticalPadding = 13.dp, onClick = { - viewModel.setEvent( - OnBoardingContract.Event.NavigateButtonClicked( - Screens.Register.OnBoardingLoadingDoctor.route, - Screens.Register.OnBoardingCheckDoctor.route - ) - ) - viewModel.setEvent(OnBoardingContract.Event.NextButtonFinal( - OnBoardingRequest( - centerName = "", - city = "", - district = "", - protectorPhoneNumber = "01088644622", - rolesType = "ROLE_DOCTOR", - fcmToken = "", - doctorLicenseNumber = "" - ) - )) + viewModel.setEvent(OnBoardingContract.Event.NextButtonFinalDoctor( + certifinumber = textState.value + )) }, textStyle = RemindTheme.typography.b2Bold ) } } +} + +@Preview +@Composable +fun DoctorPreview() { + Text( + text = stringResource(id = R.string.정신질환_환자_사례관리), + style = RemindTheme.typography.b3Medium.copy( + color = RemindTheme.colors.grayscale_3, + lineHeight = 49.sp + ) + ) } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingContract.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingContract.kt index 699bd8c..54238cd 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingContract.kt @@ -7,24 +7,24 @@ import com.example.remind.core.base.UiEffect import com.example.remind.core.base.UiEvent import com.example.remind.core.base.UiState import com.example.remind.data.model.request.OnBoardingRequest -import com.example.remind.feature.screens.auth.login.LoginContract class OnBoardingContract { data class State( val selectedType: String? = null, val userName: String = "", val moveAble: Boolean = false, - val fcmToken: String = "" + val fcmToken: String = "", + val userInfo: OnBoardingRequest = OnBoardingRequest() ): UiState sealed class Event: UiEvent { data class DoctorButtonClicked(val context: Context): Event() data class CenterButtonClicked(val context: Context): Event() data class PatienceButtonClicked(val context: Context): Event() - data class NextButtonClicked(val context: Context): Event() - data class NextButtonFinal(val onBoardingData: OnBoardingRequest): Event() - data class NextButtonToPatience(val context: Context): Event() - data class NavigateButtonClicked(val destinationRoute: String, val currentRoute: String): Event() + data class NextButtonFinalPatience(val number: String): Event() + data class NextButtonFinalDoctor(val certifinumber: String): Event() + data class NavigateButtonClicked(val destinationRoute: String, val currentRoute: String, val inclusive: Boolean): Event() + data class StoreUserInfoButtonClicked(val info: OnBoardingRequest): Event() } sealed class Effect: UiEffect { diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingFinal.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingFinal.kt index 3056e0d..0026075 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingFinal.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingFinal.kt @@ -1,6 +1,5 @@ package com.example.remind.feature.screens.auth.onboarding -import android.graphics.Paint import android.widget.Toast import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box @@ -8,9 +7,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxHeight 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.width import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -24,7 +21,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController import com.example.remind.R @@ -63,7 +59,8 @@ fun OnBoardingFinalScreen( onClick = { viewModel.setEvent(OnBoardingContract.Event.NavigateButtonClicked( Screens.Patience.route, - Screens.Register.OnBoardingFinal.route + Screens.Register.OnBoardingFinal.route, + true )) } ) @@ -74,7 +71,8 @@ fun OnBoardingFinalScreen( onClick = { viewModel.setEvent(OnBoardingContract.Event.NavigateButtonClicked( Screens.Doctor.DoctorMain.route, - Screens.Register.OnBoardingFinal.route + Screens.Register.OnBoardingFinal.route, + true )) } ) @@ -85,7 +83,8 @@ fun OnBoardingFinalScreen( onClick = { viewModel.setEvent(OnBoardingContract.Event.NavigateButtonClicked( Screens.Center.CenterMain.route, - Screens.Register.OnBoardingFinal.route + Screens.Register.OnBoardingFinal.route, + true )) }, ) @@ -100,7 +99,7 @@ fun PatienceFinal( name: String, onClick: () -> Unit ) { - var title = stringResource(id = R.string.반가워요_환자님, name) + var title = "반가워요!" Box( modifier = modifier.fillMaxSize() ) { @@ -124,8 +123,8 @@ fun PatienceFinal( Text( modifier = modifier .padding(start = 20.dp, end = 20.dp), - text = stringResource(id = R.string.오늘_하루의_통합적_기분을_선택해주세요), - style = RemindTheme.typography.b1Medium.copy(color = RemindTheme.colors.white) + text = "건강한 회복의 여정을 함께할게요.\n그럼 시작해볼까요?", + style = RemindTheme.typography.b1Medium.copy(color = RemindTheme.colors.white, lineHeight = 24.sp) ) } Image( diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingLoadingDoctor.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingLoadingDoctor.kt index 5b2025a..e4d5da5 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingLoadingDoctor.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingLoadingDoctor.kt @@ -3,13 +3,12 @@ package com.example.remind.feature.screens.auth.onboarding import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale @@ -18,7 +17,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController import com.example.remind.R import com.example.remind.core.designsystem.theme.RemindTheme @@ -26,12 +25,15 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collectLatest @Composable -fun OnBoardingLoadingDoctorScreen(navController: NavHostController) { - val viewModel: OnBoardingViewModel = hiltViewModel() +fun OnBoardingLoadingDoctorScreen( + navController: NavHostController, + viewModel: OnBoardingViewModel +) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() val effectFlow = viewModel.effect LaunchedEffect(true) { delay(3000) - //viewModel.navigateToFinal() + viewModel.navigateToFinal() effectFlow.collectLatest { effect-> when(effect) { is OnBoardingContract.Effect.NavigateTo -> { @@ -59,7 +61,7 @@ fun OnBoardingLoadingDoctorScreen(navController: NavHostController) { ) { Text( modifier = Modifier.padding(bottom = 12.dp), - text = stringResource(id = R.string.만나서_반갑습니다_), + text = stringResource(id = R.string.만나서_반갑습니다_, uiState.userName ), style = RemindTheme.typography.h1Bold.copy( color = RemindTheme.colors.white, lineHeight = 40.sp diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt index 057e267..fce0ca7 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingPatience.kt @@ -77,7 +77,7 @@ fun OnBoardingPatienceScreen( ) { BasicOnBoardingAppBar( modifier = Modifier.fillMaxWidth(), - weight = 0.5f, + weight = 0.7f, title = stringResource(id = R.string.사용자_정보) ) Text( @@ -114,7 +114,8 @@ fun OnBoardingPatienceScreen( roundedShape = 8.dp, hintText = stringResource(id = R.string.번호를_입력해주세요), topPadding = 12.dp, - bottomPadding = 12.dp + bottomPadding = 12.dp, + maxLine = 1 ) Spacer(modifier = Modifier.height(12.dp)) @@ -131,17 +132,7 @@ fun OnBoardingPatienceScreen( backgroundColor = RemindTheme.colors.main_6, text = stringResource(id = R.string.다음), onClick = { - viewModel.setEvent(OnBoardingContract.Event.NextButtonFinal( - OnBoardingRequest( - centerName = "", - city = "", - district = "", - protectorPhoneNumber = textState.value, - rolesType = "ROLE_PATIENT", - fcmToken = "", - doctorLicenseNumber = "" - ) - )) + viewModel.setEvent(OnBoardingContract.Event.NextButtonFinalPatience(number = textState.value)) }, textColor = RemindTheme.colors.white, enable = true diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingUserInfoScreen.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingUserInfoScreen.kt new file mode 100644 index 0000000..b3daa39 --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingUserInfoScreen.kt @@ -0,0 +1,259 @@ +package com.example.remind.feature.screens.auth.onboarding + +import androidx.compose.foundation.background +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.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Checkbox +import androidx.compose.material3.CheckboxDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateMapOf +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.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavHostController +import com.example.remind.R +import com.example.remind.core.common.component.BasicButton +import com.example.remind.core.common.component.BasicOnBoardingAppBar +import com.example.remind.core.common.component.RemindTextField +import com.example.remind.core.designsystem.theme.RemindTheme +import com.example.remind.data.model.request.OnBoardingRequest +import kotlinx.coroutines.flow.collectLatest + +@Composable +fun OnBoardingUserInfoScreen( + navController: NavHostController, + viewModel:OnBoardingViewModel +) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val effectFlow = viewModel.effect + val textStates = remember { mutableStateMapOf() } + val fieldKeys = listOf("nameField", "phnumberField", "bornField", "hospitalField") + var isCheckedMale by remember{ mutableStateOf(false) } + var isCheckedFeMale by remember{ mutableStateOf(false) } + + LaunchedEffect(true) { + effectFlow.collectLatest { effect -> + when(effect) { + is OnBoardingContract.Effect.NavigateTo -> { + navController.navigate(effect.destination, effect.navOptions) + } + + else -> {} + } + } + } + RemindTheme { + Column( + modifier = Modifier + .fillMaxSize() + .padding(start = 20.dp, end = 20.dp) + .background(color = RemindTheme.colors.white) + ) { + BasicOnBoardingAppBar( + modifier = Modifier.fillMaxWidth(), + weight = 0.5f, + title = "" + ) + Text( + modifier = Modifier.padding(top = 35.dp), + textAlign = TextAlign.Start, + text = "사용자 정보 입력", + style = RemindTheme.typography.h1Bold.copy(color = RemindTheme.colors.text) + ) + Text( + modifier = Modifier.padding(top = 12.dp), + textAlign = TextAlign.Start, + text = "원활한 서비스 이용을 위한\n사용자의 정보를 입력해주세요!", + style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.grayscale_3, lineHeight = 22.sp) + ) + Text( + modifier = Modifier.padding(top = 34.dp), + text= "성함", + style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.text) + ) + RemindTextField( + modifier = Modifier + .fillMaxWidth() + .padding(top = 4.dp), + onTextChanged = { newText -> textStates[fieldKeys[0]] = newText }, + text = textStates[fieldKeys[0]] ?: "", + roundedShape = 8.dp, + hintText = "사용자님의 성함을 입력해주세요.", + topPadding = 13.dp, + bottomPadding = 13.dp, + maxLine = 1 + ) + Text( + modifier = Modifier.padding(top = 20.dp), + text= "성별", + style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.text) + ) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Box( + modifier = Modifier + .weight(0.5f) + .padding(end = 12.dp) + .background( + color = RemindTheme.colors.slate_100, + shape = RoundedCornerShape(8.dp) + ) + ) { + Row( + modifier = Modifier.padding(start = 15.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Checkbox( + checked = isCheckedMale, + colors = CheckboxDefaults.colors( + checkedColor = RemindTheme.colors.main_6, + uncheckedColor = Color(0xFF6B7280), + checkmarkColor = RemindTheme.colors.white + ), + onCheckedChange = { isCheckedMale = it } + ) + Text( + modifier = Modifier.padding(start = 20.dp), + text = "남", + style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.text) + ) + } + } + Box( + modifier = Modifier + .weight(0.5f) + .background( + color = RemindTheme.colors.slate_100, + shape = RoundedCornerShape(8.dp) + ) + ) { + Row( + modifier = Modifier.padding(start = 15.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Checkbox( + checked = isCheckedFeMale, + colors = CheckboxDefaults.colors( + checkedColor = RemindTheme.colors.main_6, + uncheckedColor = Color(0xFF6B7280), + checkmarkColor = RemindTheme.colors.white + ), + onCheckedChange = { isCheckedFeMale = it } + ) + Text( + modifier = Modifier.padding(start = 20.dp), + text = "여", + style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.text) + ) + } + } + } + Text( + modifier = Modifier.padding(top = 20.dp), + text= "전화번호", + style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.text) + ) + RemindTextField( + modifier = Modifier + .fillMaxWidth() + .padding(top = 4.dp), + onTextChanged = { newText -> textStates[fieldKeys[1]] = newText }, + text = textStates[fieldKeys[1]] ?: "", + roundedShape = 8.dp, + hintText = "번호를 입력헤주세요.", + topPadding = 13.dp, + bottomPadding = 13.dp, + maxLine = 1 + ) + Text( + modifier = Modifier.padding(top = 20.dp), + text= "출생연도", + style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.text) + ) + RemindTextField( + modifier = Modifier + .fillMaxWidth() + .padding(top = 4.dp), + onTextChanged = { newText -> textStates[fieldKeys[2]] = newText }, + text = textStates[fieldKeys[2]] ?: "", + roundedShape = 8.dp, + hintText = "출생연도를 입력해주세요.", + topPadding = 13.dp, + bottomPadding = 13.dp, + maxLine = 1 + ) + if(uiState.selectedType == "ROLE_DOCTOR") { + Text( + modifier = Modifier.padding(top = 20.dp), + text= "병원이름", + style = RemindTheme.typography.b2Medium.copy(color = RemindTheme.colors.text) + ) + RemindTextField( + modifier = Modifier + .fillMaxWidth() + .padding(start = 20.dp, end = 20.dp, top = 4.dp), + onTextChanged = { newText -> textStates[fieldKeys[3]] = newText }, + text = textStates[fieldKeys[3]] ?: "", + roundedShape = 8.dp, + hintText = "소속 병원 이름을 입력해주세요.", + topPadding = 13.dp, + bottomPadding = 13.dp, + maxLine = 1 + ) + } + Spacer(modifier = Modifier.weight(1f)) + BasicButton( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 32.dp), + text = stringResource(id = R.string.다음), + RoundedCorner = 12.dp, + backgroundColor = if(textStates[fieldKeys[0]] != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + textColor = if(textStates[fieldKeys[0]] != null) RemindTheme.colors.white else RemindTheme.colors.slate_300, + verticalPadding = 13.dp, + onClick = { + viewModel.setEvent( + OnBoardingContract.Event.StoreUserInfoButtonClicked( + info = OnBoardingRequest( + centerName = "", + city = "", + district = "", + protectorPhoneNumber = "", + rolesType = uiState.selectedType!!, + fcmToken = "", + doctorLicenseNumber = textStates[fieldKeys[3]] ?: "", + birthday = textStates[fieldKeys[2]] ?: "", + phoneNumber = textStates[fieldKeys[1]] ?: "", + gender = if(isCheckedMale == true) "남" else "여", + name = textStates[fieldKeys[0]] ?: "" + ) + ) + ) + }, + textStyle = RemindTheme.typography.b2Bold + ) + } + } +} diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt index 592d7d6..42e7e97 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/OnBoardingViewModel.kt @@ -51,22 +51,41 @@ class OnBoardingViewModel @Inject constructor( updateState(currentState.copy(selectedType = "ROLE_PATIENT")) saveUserType("ROLE_PATIENT") } - is OnBoardingContract.Event.NextButtonFinal -> { + //환자가 마지막 끝나는 화면으로 가는 기능 + is OnBoardingContract.Event.NextButtonFinalPatience -> { viewModelScope.launch { - postOnBoarding(event.onBoardingData.copy(fcmToken = currentState.fcmToken)) + updateState(currentState.copy( + userInfo = currentState.userInfo.copy( + fcmToken = currentState.fcmToken, + protectorPhoneNumber = event.number + ) + )) + postOnBoarding(currentState.userInfo) navigateToRoute(Screens.Register.OnBoardingFinal.route, Screens.Register.OnBoardingPatience.route, true) - Log.d("dklfawek", "${currentState.selectedType}") } } - is OnBoardingContract.Event.NextButtonToPatience -> { - //navigateToRoute(event.destinationRoute, event.currentRoute) + //의사가 마지막 끝나는 화면으로 가는 기능 + is OnBoardingContract.Event.NextButtonFinalDoctor -> { + viewModelScope.launch { + updateState(currentState.copy( + userInfo = currentState.userInfo.copy( + fcmToken = event.certifinumber + ) + )) + postOnBoarding(currentState.userInfo) + navigateToRoute(Screens.Register.OnBoardingLoadingDoctor.route, Screens.Register.OnBoardingCheckDoctor.route, true) + } } - is OnBoardingContract.Event.NextButtonClicked -> { + //사용자 정보 작성하고 각자 입장의 온보딩으로 이동 + is OnBoardingContract.Event.StoreUserInfoButtonClicked -> { + updateState(currentState.copy( + userInfo = event.info + )) navigateToNext(currentState.selectedType!!) } - //의사부터 이걸로 통합시킴 + //입장 상관없이 공통의 경로를 명시한 is OnBoardingContract.Event.NavigateButtonClicked -> { - navigateToRoute(event.destinationRoute, event.currentRoute, false) + navigateToRoute(event.destinationRoute, event.currentRoute, event.inclusive) } else ->{} } @@ -80,13 +99,13 @@ class OnBoardingViewModel @Inject constructor( fun navigateToNext(selectType: String) { if(selectType == "ROLE_DOCTOR") { - navigateToRoute(Screens.Register.OnBoardingCheckDoctor.route, Screens.Register.SelectType.route, false) + navigateToRoute(Screens.Register.OnBoardingCheckDoctor.route, Screens.Register.OnBoardingUserInfo.route, false) } if(selectType == "ROLE_PATIENT") { - navigateToRoute(Screens.Register.OnBoardingPatience.route, Screens.Register.SelectType.route,false) + navigateToRoute(Screens.Register.OnBoardingPatience.route, Screens.Register.OnBoardingUserInfo.route,false) } if(selectType == "ROLE_CENTER") { - navigateToRoute(Screens.Register.OnBoardingCenter.route, Screens.Register.SelectType.route,false) + navigateToRoute(Screens.Register.OnBoardingCenter.route, Screens.Register.OnBoardingUserInfo.route,false) } } @@ -102,6 +121,20 @@ class OnBoardingViewModel @Inject constructor( ) ) } + //로딩창 이후 final 화면으로 이동 위함 + fun navigateToFinal() { + postEffect( + OnBoardingContract.Effect.NavigateTo( + destination = Screens.Register.OnBoardingFinal.route, + navOptions = navOptions { + popUpTo(Screens.Register.OnBoardingLoadingDoctor.route) { + inclusive = true + } + } + ) + ) + } + private fun getFcmToken() { viewModelScope.launch { diff --git a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt index feef723..4181f86 100644 --- a/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/auth/onboarding/SelectTypeScreen.kt @@ -34,6 +34,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController import com.example.remind.R +import com.example.remind.app.Screens import com.example.remind.core.common.component.BasicOnBoardingAppBar import com.example.remind.core.designsystem.theme.Pretendard import com.example.remind.core.designsystem.theme.RemindTheme @@ -61,7 +62,9 @@ fun SelectTypeScreen( } RemindTheme { Column( - modifier = Modifier.fillMaxSize() + modifier = Modifier + .fillMaxSize() + .background(color = RemindTheme.colors.white) ) { BasicOnBoardingAppBar( modifier = Modifier.fillMaxWidth(), @@ -133,7 +136,7 @@ fun SelectTypeScreen( backgroundColor = if(uiState.selectedType == null) RemindTheme.colors.slate_100 else RemindTheme.colors.main_6, text = stringResource(id = R.string.다음), onClick = { - viewModel.setEvent(OnBoardingContract.Event.NextButtonClicked(context)) + viewModel.setEvent(OnBoardingContract.Event.NavigateButtonClicked(Screens.Register.OnBoardingUserInfo.route, Screens.Register.SelectType.route, false)) }, textColor = if(uiState.selectedType == null) RemindTheme.colors.slate_300 else RemindTheme.colors.white, enable = uiState.selectedType != null diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt b/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt index f571466..5e9c9b9 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt @@ -13,6 +13,7 @@ import androidx.navigation.compose.composable import com.example.remind.feature.screens.patience.home.HomeCheeringScreen import com.example.remind.feature.screens.patience.home.HomeScreen import com.example.remind.feature.screens.patience.home.HomeViewModel +import com.example.remind.feature.screens.patience.medicine.AlarmSettingScreen import com.example.remind.feature.screens.patience.medicine.MedicineScreen import com.example.remind.feature.screens.patience.medicine.MedicineViewModel import com.example.remind.feature.screens.patience.moodchart.MoodChartScreen @@ -66,6 +67,9 @@ fun PatienceGraph( composable(route = Screens.Patience.Medicine.route) { MedicineScreen(navController, MedicineViewModel) } + composable(route = Screens.Patience.Medicine.AlarmSetting.route) { + AlarmSettingScreen(navController, MedicineViewModel) + } composable(route = Screens.Patience.MyPage.route) { MyPageScreen() } diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmSettingScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmSettingScreen.kt new file mode 100644 index 0000000..5a6b0be --- /dev/null +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmSettingScreen.kt @@ -0,0 +1,111 @@ +package com.example.remind.feature.screens.patience.medicine + +import androidx.compose.foundation.background +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.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavHostController +import com.example.remind.R +import com.example.remind.core.common.component.BasicButton +import com.example.remind.core.designsystem.theme.RemindTheme +import kotlinx.coroutines.flow.collectLatest + +@Composable +fun AlarmSettingScreen( + navController: NavHostController, viewModel: MedicineViewModel +) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val effectFlow = viewModel.effect + + val scrollState = rememberScrollState() + LaunchedEffect(true) { + effectFlow.collectLatest { effect -> + when(effect) { + is MedicineContract.Effect.NavigateTo -> { + navController.navigate(effect.destinaton, effect.navOptions) + } + else-> { + } + } + } + } + RemindTheme { + Column( + modifier = Modifier + .fillMaxSize() + .background(color = RemindTheme.colors.white) + .verticalScroll(scrollState) + ) { + Row( + modifier = Modifier.padding(start = 26.dp, top = 24.dp), + verticalAlignment = Alignment.CenterVertically + ) { + IconButton( + onClick = { /*TODO*/ } + ) { + Icon( + painter = painterResource(id = R.drawable.ic_arrowleft), + contentDescription = null + ) + } + Text( + text = "약 복용 알림 설정", + style = RemindTheme.typography.h2Bold.copy(color = RemindTheme.colors.text) + ) + } + Row( + modifier = Modifier.padding(horizontal = 20.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = "주기 설정", + style = RemindTheme.typography.b2Bold.copy(color = RemindTheme.colors.text) + ) + Spacer(modifier = Modifier.weight(1f)) + BasicButton( + modifier = Modifier.size(width = 79.dp, height = 28.dp), + text = "알림 추가", + RoundedCorner = 20.dp, + backgroundColor = RemindTheme.colors.main_6, + textColor = RemindTheme.colors.white, + verticalPadding = 5.dp, + onClick = { + //다이얼로그 동작 + }, + textStyle = RemindTheme.typography.c1Medium + ) + + } + Text( + modifier = Modifier.padding(top = 8.dp), + text = "알림을 통해 복용 시간을 놓치지 말아요!", + style = RemindTheme.typography.c1Medium.copy(color = RemindTheme.colors.grayscale_3) + ) + } + } +} + +@Composable +fun listItem( + +) { + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt index c28c599..5bd2246 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt @@ -20,7 +20,10 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.Text +import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SheetState +import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment @@ -60,15 +63,17 @@ fun findFeelingMent(feelingType: String): String? { } @OptIn(ExperimentalMaterial3Api::class) @Composable -fun MoodChartBottomSheet( +fun MoodChartBottomSheet ( modifier: Modifier = Modifier, viewModel: MoodChartViewModel, + sheetState : SheetState = rememberModalBottomSheetState(), + onDismissRequest: () -> Unit, ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() - val effectFlow = viewModel.effect val scrollState = rememberScrollState() BasicBottomSheet( - onDismissRequest = { } + onDismissRequest = onDismissRequest, + sheetState = sheetState ) { Column( modifier = modifier @@ -84,7 +89,7 @@ fun MoodChartBottomSheet( text = "날짜날짜" ) Spacer(modifier = modifier.weight(1f)) - IconButton(onClick = {}) { + IconButton(onClick = onDismissRequest) { Icon( painter = painterResource(id = R.drawable.ic_close), contentDescription = null @@ -104,11 +109,11 @@ fun MoodChartBottomSheet( ) { Image( modifier = modifier.padding(end = 4.dp), - painter = painterResource(id = findFeelingImage(uiState.dailyMood.feelingType)!!), + painter = painterResource(id = findFeelingImage(uiState.dailyMood.feelingType) ?: R.drawable.ic_verygood), contentDescription = null ) Text( - text = findFeelingText(uiState.dailyMood.feelingType)!!, + text = findFeelingText(uiState.dailyMood.feelingType) ?: "", style = RemindTheme.typography.h2Medium.copy(color = RemindTheme.colors.slate_800) ) } @@ -126,6 +131,8 @@ fun MoodChartBottomSheet( activityListItem(item = item) } } + }else { + CircularProgressIndicator() } Text( modifier = modifier.padding(top = 16.dp), @@ -145,6 +152,8 @@ fun MoodChartBottomSheet( MedicineInfo(content = item) } } + } else { + CircularProgressIndicator() } } } @@ -194,11 +203,11 @@ fun activityListItem( modifier = Modifier .size(width = 15.dp, height = 21.dp) .padding(end = 3.dp), - painter = painterResource(id = findFeelingImage(item.feelingType)!!), + painter = painterResource(id = findFeelingImage(item.feelingType) ?: R.drawable.ic_verygood), contentDescription = null ) Text ( - text = findFeelingMent(item.feelingType)!!, + text = findFeelingMent(item.feelingType) ?: "", style = RemindTheme.typography.b3Medium.copy(color = RemindTheme.colors.slate_600) ) } diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt index d77cad4..9aca41f 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt @@ -20,11 +20,16 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text +import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush @@ -55,11 +60,15 @@ import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphStyle import com.jaikeerthick.composable_graphs.composables.line.style.LineGraphVisibility import com.jaikeerthick.composable_graphs.style.LabelPosition import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch import java.time.LocalDate +@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class) @Composable fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewModel) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() val effectFlow = viewModel.effect + val sheetState = rememberModalBottomSheetState() + val coroutineScope = rememberCoroutineScope() val scrollState = rememberScrollState() val graphYaxisList = listOf( graphScoreModel(100, R.drawable.ic_verygood), @@ -68,6 +77,13 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod graphScoreModel(25, R.drawable.ic_bad), graphScoreModel(0, R.drawable.ic_terrible), ) + MoodChartBottomSheet( + viewModel = viewModel, + sheetState = sheetState, + onDismissRequest = { + coroutineScope.launch { sheetState.hide() } + } + ) LaunchedEffect(true) { effectFlow.collectLatest { effect -> when(effect) { @@ -115,7 +131,11 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod backgroundColor = RemindTheme.colors.main_6, textColor = RemindTheme.colors.white, verticalPadding = 18.dp, - onClick = { }, + onClick = { + viewModel.setEvent(MoodChartContract.Event.ClickToBottomSheet( + "2024-05-${uiState.date}" + )) + }, textStyle = RemindTheme.typography.b3Bold ) Spacer(modifier = Modifier.height(8.dp)) @@ -169,7 +189,7 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod } } Spacer(modifier = Modifier.width(25.dp)) - if(uiState.xAxisData.isNotEmpty()) { + if(uiState.xAxisData.isNotEmpty() && uiState.yAxisData.isNotEmpty()) { GraphComponent( modifier = Modifier.weight(4f), dateListX = uiState.xAxisData, diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt index e59be99..6baf20e 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt @@ -29,7 +29,6 @@ class MoodChartViewModel @Inject constructor( init { viewModelScope.launch { getMoodChartData(year, month, date-3) - extractList() getFeelingPerCent() } } @@ -41,6 +40,10 @@ class MoodChartViewModel @Inject constructor( is MoodChartContract.Event.storeDate -> { updateState(currentState.copy(date = event.date)) } + is MoodChartContract.Event.ClickToBottomSheet -> { + getDailyMood(event.moodDate) + getDailyMedicine(event.moodDate) + } else ->{} } } @@ -52,7 +55,7 @@ class MoodChartViewModel @Inject constructor( is ApiResult.Success -> { updateState(currentState.copy( moodChartData = result.data.data, - xAxisData = result.data.data.moodChartDtos.map { it.localDate }, + xAxisData = result.data.data.moodChartDtos.map { "${it.day}일" }, yAxisData = result.data.data.moodChartDtos.map { it.score } )) } @@ -65,9 +68,11 @@ class MoodChartViewModel @Inject constructor( val result = getFeelingPercentUseCase.invoke() when(result) { is ApiResult.Success -> { - updateState(currentState.copy( - feelingTotalPerCent = result.data.data - )) + if(result.data.data != null) { + updateState(currentState.copy( + feelingTotalPerCent = result.data.data + )) + } } else ->{} } @@ -99,20 +104,7 @@ class MoodChartViewModel @Inject constructor( } } } - fun extractList() { - val size = uiState.value.moodChartData.moodChartDtos.size - val list: MutableList = mutableListOf() - for(i in 0..size-1) { - val data = formattingDate(uiState.value.moodChartData.moodChartDtos.get(i).localDate) - list.add("${data}일") - } - updateState(currentState.copy(xAxisData = list)) - } - fun formattingDate(dateString: String):Int { - val extractString = dateString.takeLast(2) - val date: Int = extractString.toInt() - return date - } + fun setToastMessage(text: String) { diff --git a/app/src/main/res/drawable/ic_main_logo.xml b/app/src/main/res/drawable/ic_main_logo.xml new file mode 100644 index 0000000..196b27e --- /dev/null +++ b/app/src/main/res/drawable/ic_main_logo.xml @@ -0,0 +1,21 @@ + + + + + + From 6873aa54866c9f4ee6bdf67dd516ee2ce66bc3e7 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Wed, 22 May 2024 17:26:09 +0900 Subject: [PATCH 17/19] =?UTF-8?q?[feat]=20=EC=98=A4=EB=8A=98=20=EA=B8=B0?= =?UTF-8?q?=EB=B6=84=20=EC=B6=94=EA=B0=80=20=EB=94=94=EC=9E=90=EC=9D=B8=20?= =?UTF-8?q?=EB=B0=8F=20=EC=83=81=ED=83=9C=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20=EB=B0=A9=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/common/component/MedicineItem.kt | 27 +++++++-- .../model/request/SetMedicineInfoRequest.kt | 1 - .../data/model/request/WritingMoodRequest.kt | 14 ++--- .../feature/screens/patience/PatienceGraph.kt | 4 +- .../patience/home/HomeCheeringScreen.kt | 6 +- .../screens/patience/home/HomeContract.kt | 11 +++- .../patience/home/HomeMedicineDialog.kt | 47 +++++++++------- .../screens/patience/home/HomeScreen.kt | 26 +++++---- .../screens/patience/home/HomeViewModel.kt | 44 +++++++++++++-- .../patience/writing/WritingContract.kt | 22 +++----- .../writing/WritingMoodStep1Screen.kt | 6 +- .../writing/WritingMoodStep2FeelingScreen.kt | 26 +++------ .../writing/WritingMoodStep2LastScreen.kt | 11 ++-- .../writing/WritingMoodStep2Screen.kt | 16 +++--- .../writing/WritingMoodStep3Screen.kt | 16 ++---- .../patience/writing/WritingViewModel.kt | 56 ++++++++++++------- 16 files changed, 199 insertions(+), 134 deletions(-) diff --git a/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt b/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt index f66f0db..e2e6234 100644 --- a/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt +++ b/app/src/main/java/com/example/remind/core/common/component/MedicineItem.kt @@ -71,7 +71,7 @@ fun MedicineItem( ) } Spacer(modifier = Modifier.height(4.dp)) - if(!isTaking) { + if(isTaking == false && notTakingReason == "") { Row( modifier = Modifier.fillMaxWidth() ) { @@ -107,16 +107,31 @@ fun MedicineItem( ) ) } - } else { + } else if(isTaking == false && notTakingReason != "") { Text( modifier = Modifier .fillMaxWidth() .background( color = RemindTheme.colors.slate_500, shape = RoundedCornerShape(bottomStart = 12.dp, bottomEnd = 12.dp) - ) - .clickable { doseClick() }, - text = if(notTakingReason != "") "미복용" else isTakingTime, + ), + text = "미복용", + textAlign= TextAlign.Center, + style = RemindTheme.typography.c1Bold.copy( + color = RemindTheme.colors.white, + lineHeight = 20.sp + ) + ) + } + else { + Text( + modifier = Modifier + .fillMaxWidth() + .background( + color = RemindTheme.colors.slate_500, + shape = RoundedCornerShape(bottomStart = 12.dp, bottomEnd = 12.dp) + ), + text = isTakingTime, textAlign= TextAlign.Center, style = RemindTheme.typography.c1Bold.copy( color = RemindTheme.colors.white, @@ -131,5 +146,5 @@ fun MedicineItem( @Preview @Composable fun ItemPreview() { - MedicineItem(time = "아침", score= 2.0f, doseClick = {}, unadministeredClick = {}, isTaking = false, isTakingTime = "오전 7:00", notTakingReason = "미복용") + MedicineItem(time = "아침", score= 2.0f, doseClick = {}, unadministeredClick = {}, isTaking = true, isTakingTime = "", notTakingReason = "") } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/request/SetMedicineInfoRequest.kt b/app/src/main/java/com/example/remind/data/model/request/SetMedicineInfoRequest.kt index aaf5e1d..6cab9e8 100644 --- a/app/src/main/java/com/example/remind/data/model/request/SetMedicineInfoRequest.kt +++ b/app/src/main/java/com/example/remind/data/model/request/SetMedicineInfoRequest.kt @@ -4,7 +4,6 @@ import kotlinx.serialization.Serializable @Serializable data class SetMedicineInfoRequest( - val date: String, val isTaking: Boolean, val medicinesType: String, val notTakingReason: String diff --git a/app/src/main/java/com/example/remind/data/model/request/WritingMoodRequest.kt b/app/src/main/java/com/example/remind/data/model/request/WritingMoodRequest.kt index ddd1d63..eab1e79 100644 --- a/app/src/main/java/com/example/remind/data/model/request/WritingMoodRequest.kt +++ b/app/src/main/java/com/example/remind/data/model/request/WritingMoodRequest.kt @@ -1,13 +1,13 @@ package com.example.remind.data.model.request data class WritingMoodRequest( - val detail: String, - val feelingType: String, - val localDate: String, - val moodActivities: List + val detail: String="", + val feelingType: String = "", + val localDate: String = "", + val moodActivities: List = emptyList() ) data class MoodActivity( - val activityId: Int, - val detail: String, - val feelingType: String + val activityId: Int=0, + val detail: String="", + val feelingType: String="" ) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt b/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt index 5e9c9b9..d5f6950 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/PatienceGraph.kt @@ -41,7 +41,7 @@ fun PatienceGraph( startDestination = Screens.Patience.Home.route ) { composable(route = Screens.Patience.Home.route) { - HomeScreen(navController) + HomeScreen(navController,HomeviewModel) } composable(route = Screens.Patience.Home.WritingMoodStep1.route) { WritingMoodStep1Screen(navController, WritingviewModel) @@ -59,7 +59,7 @@ fun PatienceGraph( WritingMoodStep3Screen(navController, WritingviewModel) } composable(route = Screens.Patience.Home.SplashCheering.route) { - HomeCheeringScreen(navController) + HomeCheeringScreen(navController,HomeviewModel) } composable(route = Screens.Patience.MoodChart.route) { MoodChartScreen(navController, MoodChartViewModel) diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeCheeringScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeCheeringScreen.kt index df2fd8c..5be1f57 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeCheeringScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeCheeringScreen.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel @@ -15,11 +16,11 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collectLatest @Composable -fun HomeCheeringScreen(navController: NavHostController) { - val viewModel: HomeViewModel = hiltViewModel() +fun HomeCheeringScreen(navController: NavHostController, viewModel: HomeViewModel ) { val effectFlow = viewModel.effect LaunchedEffect(true) { delay(3000) + viewModel.navigateToHome() effectFlow.collectLatest { effect-> when(effect) { is HomeContract.Effect.NavigateTo -> { @@ -33,6 +34,7 @@ fun HomeCheeringScreen(navController: NavHostController) { Image( modifier = Modifier.fillMaxSize(), painter = painterResource(id = R.drawable.img_example_cheer), + contentScale = ContentScale.FillWidth, contentDescription = null ) diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt index 2057de1..1031ab9 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeContract.kt @@ -13,17 +13,22 @@ class HomeContract { val sosDialogState: Boolean = false, val medicineDialogState:Boolean = false, val medicineDailyData: List = emptyList(), - val notTakingReason: String? = null + val notTakingReason: String? = null, + val clickTime: String = "" ): UiState sealed class Event: UiEvent { data class WritingButtonClicked(val context: Context): Event() object showSosDialog: Event() + //data class showSosDialog(val medicineTime: String): Event() object DismissDialog: Event() - object showMediDialog: Event() + //object showMediDialog: Event() + data class showMediDialog(val medicineTime: String): Event() object dismissMediDialog: Event() data class CallButtonClicked(val context: Context, val number: String):Event() - data class SendNotTakingReason(val medicineTime: String,val date: String, val notTakingReason: String):Event() + data class SendNotTakingReason(val context: Context):Event() + data class medicineSuccess(val medicineTime: String):Event() + data class setNotTakingReason(val notTakingReason: String):Event() } sealed class Effect: UiEffect { data class NavigateTo( diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt index ee4a603..c3266cd 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeMedicineDialog.kt @@ -35,12 +35,14 @@ fun HomeMedicineDialog ( onDismissClick: () -> Unit, onConfirmClick: () -> Unit, showDialog:Boolean, + viewModel: HomeViewModel, ) { BasicDialog( popupContent = { ContentMedicineDialog( onDismissClick = onDismissClick, - onConfirmClick = onConfirmClick) + onConfirmClick = onConfirmClick, + viewModel = viewModel) }, showDialog = showDialog ) @@ -52,8 +54,9 @@ fun ContentMedicineDialog( modifier: Modifier = Modifier, onDismissClick: () -> Unit, onConfirmClick: () -> Unit, + viewModel: HomeViewModel ) { - val viewModel: HomeViewModel = hiltViewModel() + //val viewModel: HomeViewModel = hiltViewModel() val uiState by viewModel.uiState.collectAsStateWithLifecycle() val reasonList = listOf( stringResource(id = R.string.까먹었어요), @@ -92,17 +95,26 @@ fun ContentMedicineDialog( .align(Alignment.Center) .padding(top = 65.dp, start = 15.dp, end = 15.dp) ) { - Row { + Row( + modifier = Modifier.fillMaxWidth() + ) { for(i in 0..1) { Box( modifier = modifier + .weight(1f) + .padding(end = 3.dp) .background( - color = if (uiState.notTakingReason != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + color = if (uiState.notTakingReason == reasonList.get(i)) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, shape = RoundedCornerShape(20.dp) ) .padding(end = 3.dp) .clickable( - onClick = { uiState.copy(notTakingReason = reasonList.get(i)) } + enabled = true, + onClick = { + viewModel.setEvent( + HomeContract.Event.setNotTakingReason(reasonList.get(i)) + ) + } ) ) { Text( @@ -120,13 +132,20 @@ fun ContentMedicineDialog( for(i in 2..3) { Box( modifier = modifier + .weight(1f) + .padding(end = 3.dp) .background( - color = if (uiState.notTakingReason != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + color = if (uiState.notTakingReason == reasonList.get(i)) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, shape = RoundedCornerShape(20.dp) ) .padding(end = 3.dp) .clickable( - onClick = { uiState.copy(notTakingReason = reasonList.get(i)) } + enabled = true, + onClick = { + viewModel.setEvent( + HomeContract.Event.setNotTakingReason(reasonList.get(i)) + ) + } ) ) { Text( @@ -154,18 +173,4 @@ fun ContentMedicineDialog( } } -} - - -fun saveText(text: String): String { - var selectText = text - return selectText -} - -@Preview(showBackground = false) -@Composable -fun DialogPreview() { - ContentMedicineDialog( - onDismissClick = { }, - onConfirmClick = {}) } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt index b66c180..113fb05 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeScreen.kt @@ -16,6 +16,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box 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 @@ -23,6 +24,7 @@ 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.widthIn import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed @@ -48,10 +50,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat -import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController import com.example.remind.R @@ -66,8 +66,7 @@ import java.time.format.DateTimeFormatter @RequiresApi(Build.VERSION_CODES.O) @Composable -fun HomeScreen(navController: NavHostController) { - val viewModel: HomeViewModel = hiltViewModel() +fun HomeScreen(navController: NavHostController, viewModel: HomeViewModel) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() val effectFlow = viewModel.effect val context = LocalContext.current @@ -129,9 +128,10 @@ fun HomeScreen(navController: NavHostController) { HomeMedicineDialog( onDismissClick = { viewModel.reduceState(HomeContract.Event.dismissMediDialog) }, onConfirmClick = { - viewModel.setEvent(HomeContract.Event.SendNotTakingReason(medicineTime, sendDate, uiState.notTakingReason!!)) + viewModel.setEvent(HomeContract.Event.SendNotTakingReason(context)) }, - showDialog = uiState.medicineDialogState + showDialog = uiState.medicineDialogState, + viewModel = viewModel ) } @@ -204,7 +204,7 @@ fun HomeScreen(navController: NavHostController) { EmptyMedicineList() } else { LazyRow( - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), ) { itemsIndexed(uiState.medicineDailyData) {index, item -> var timeText: String= when(item.medicinesType) { @@ -214,14 +214,16 @@ fun HomeScreen(navController: NavHostController) { } MedicineItem( modifier = Modifier - .fillMaxWidth() - .padding(end = 7.dp), + .padding(end = 7.dp) + .widthIn(min = 100.dp, max = 102.dp), time = timeText, score = item.importance.toFloat(), doseClick = { - viewModel.setEvent(HomeContract.Event.showMediDialog) + viewModel.setEvent(HomeContract.Event.medicineSuccess(item.medicinesType)) + }, + unadministeredClick = { + viewModel.setEvent(HomeContract.Event.showMediDialog(item.medicinesType)) }, - unadministeredClick = {}, isTaking = item.isTaking ?: false, isTakingTime = item.takingTime ?: "", notTakingReason = item.notTakingReason ?: "" @@ -266,7 +268,7 @@ fun HomeTopBar( verticalAlignment = Alignment.CenterVertically ) { Image( - painter = painterResource(id = R.drawable.ic_logo), + painter = painterResource(id = R.drawable.ic_main_logo), contentDescription = null, modifier = modifier .size( diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt index c80085a..a50a94e 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt @@ -30,12 +30,14 @@ class HomeViewModel @Inject constructor( ) } is HomeContract.Event.showSosDialog -> { + //updateState(currentState.copy(clickTime = event.medicineTime)) updateState(currentState.copy(sosDialogState = true)) } is HomeContract.Event.DismissDialog -> { updateState(currentState.copy(sosDialogState = false)) } is HomeContract.Event.showMediDialog -> { + updateState(currentState.copy(clickTime = event.medicineTime)) updateState(currentState.copy(medicineDialogState = true)) } is HomeContract.Event.dismissMediDialog -> { @@ -45,15 +47,35 @@ class HomeViewModel @Inject constructor( setSosCall(event.context, event.number) } is HomeContract.Event.SendNotTakingReason -> { + sendNotTakingReason(currentState.clickTime, currentState.notTakingReason ?: "") + updateState(currentState.copy(medicineDialogState = false)) + } + //미복용 사유 클릭 + is HomeContract.Event.setNotTakingReason -> { + updateState(currentState.copy(notTakingReason = event.notTakingReason)) + } + //복용눌렀을때 + is HomeContract.Event.medicineSuccess -> { + sendTakingReason(event.medicineTime) navigateToRoute( destination = Screens.Patience.Home.SplashCheering.route, current = Screens.Patience.Home.route, - inclusiveData = false + inclusiveData = true ) - sendNotTakingReason(event.medicineTime, event.date, event.notTakingReason) } } } + fun navigateToHome() { + postEffect( + HomeContract.Effect.NavigateTo( + destinaton = Screens.Patience.Home.route, + navOptions = navOptions { + popUpTo(Screens.Patience.Home.SplashCheering.route) { + inclusive = true + } + } + )) + } fun navigateToRoute(destination: String, current: String, inclusiveData: Boolean) { postEffect( HomeContract.Effect.NavigateTo( @@ -94,10 +116,9 @@ class HomeViewModel @Inject constructor( } } - fun sendNotTakingReason(medicineTime: String, date: String, notTakingReason: String) { + fun sendNotTakingReason(medicineTime: String, notTakingReason: String) { viewModelScope.launch { val result = setMedicineInfoUseCase.invoke(SetMedicineInfoRequest( - date = date, isTaking = false, medicinesType = medicineTime, notTakingReason = notTakingReason @@ -110,6 +131,21 @@ class HomeViewModel @Inject constructor( } } } + fun sendTakingReason(medicineTime: String) { + viewModelScope.launch { + val result = setMedicineInfoUseCase.invoke(SetMedicineInfoRequest( + isTaking = true, + medicinesType = medicineTime, + notTakingReason = "" + )) + when(result) { + is ApiResult.Success -> { + Log.d("HomeViewModel", "success") + } + else -> {} + } + } + } fun setToastMessage(text: String) { postEffect(HomeContract.Effect.Toastmessage(text)) diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt index 8b5fbca..0a600e8 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt @@ -7,34 +7,28 @@ import com.example.remind.core.base.UiEffect import com.example.remind.core.base.UiEvent import com.example.remind.core.base.UiState import com.example.remind.data.model.request.MoodActivity +import com.example.remind.data.model.request.WritingMoodRequest import com.example.remind.data.model.response.Activity class WritingContract { data class State( - val totalFeelingType: String = "", + //디폴트 활동 조회 val ActivityList: List = emptyList(), - val MoodActivityList: List = emptyList(), - val detail: String = "", - val activityId: Int = 0, - val activityName: String = "", - val feelingType: String = "", - val thanksToDetail: String = "" + val moodActivity: MoodActivity = MoodActivity(), + val writingMoodRequest: WritingMoodRequest = WritingMoodRequest() ): UiState sealed class Event: UiEvent { + data class FeelingButtonClicked(val feelingType: String): Event() data class NextButtonClicked(val destinationRoute: String, val currentRoute: String): Event() data class PreviousButtonClicked(val destinationRoute: String, val currentRoute: String): Event() - data class ActivityButtonClicked(val activityId: Int, val activityName: String): Event() + data class ActivityButtonClicked(val activityId: Int): Event() data class FeelingActivityButtonClicked(val feelingType: String): Event() - data class StoreFeelingListItem( - val activityData: MoodActivity, - val destinationRoute: String, - val currentRoute: String - ): Event() + data class StoreFeelingListItem(val detail: String): Event() data class NavigateToHome(val context: Context): Event() data class NavigateToStep2(val destinationRoute: String, val currentRoute: String): Event() - data class SendInfoButton(val destinationRoute: String, val currentRoute: String, val localDate: String, val detail:String): Event() + data class SendInfoButton(val destinationRoute: String, val currentRoute: String): Event() } sealed class Effect: UiEffect { diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep1Screen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep1Screen.kt index 1c40de4..c5fd383 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep1Screen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep1Screen.kt @@ -118,7 +118,7 @@ fun WritingMoodStep1Screen(navController: NavHostController, viewModel: WritingV IconContainer( feelingScoreModel = feelingList.get(i), backgroundColor = - if(uiState.totalFeelingType == feelingList.get(i).text) RemindTheme.colors.main_4 else RemindTheme.colors.white, + if(uiState.writingMoodRequest.feelingType == feelingList.get(i).text) RemindTheme.colors.main_4 else RemindTheme.colors.white, onClick = { viewModel.setEvent(WritingContract.Event.FeelingButtonClicked(feelingList.get(i).text)) } @@ -137,8 +137,8 @@ fun WritingMoodStep1Screen(navController: NavHostController, viewModel: WritingV ), text = stringResource(id = R.string.다음), RoundedCorner = 12.dp, - backgroundColor = if(uiState.totalFeelingType != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, - textColor = if(uiState.totalFeelingType != null) RemindTheme.colors.white else RemindTheme.colors.slate_300, + backgroundColor = if(uiState.writingMoodRequest.feelingType != "") RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + textColor = if(uiState.writingMoodRequest.feelingType != "") RemindTheme.colors.white else RemindTheme.colors.slate_300, verticalPadding = 13.dp, onClick = { viewModel.setEvent(WritingContract.Event.NextButtonClicked( diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt index 998fe9f..7133163 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt @@ -11,7 +11,6 @@ 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.shape.RoundedCornerShape import androidx.compose.material.Icon import androidx.compose.material.IconButton @@ -37,7 +36,6 @@ import com.example.remind.core.common.component.IconContainer import com.example.remind.core.common.component.RemindTextField import com.example.remind.core.designsystem.theme.RemindTheme import com.example.remind.data.model.FeelingScoreModel -import com.example.remind.data.model.request.MoodActivity import kotlinx.coroutines.flow.collectLatest @Composable @@ -73,7 +71,9 @@ fun WritingMoodStep2FeelingScreen(navController: NavHostController, viewModel: W RemindTheme { Column( - modifier = Modifier.padding(vertical = 20.dp) + modifier = Modifier + .background(color = RemindTheme.colors.white) + .padding(horizontal = 20.dp) ) { Spacer(modifier = Modifier.height(24.dp)) IconButton( @@ -129,11 +129,9 @@ fun WritingMoodStep2FeelingScreen(navController: NavHostController, viewModel: W IconContainer( feelingScoreModel = feelingList.get(i), backgroundColor = - if(uiState.feelingType == feelingList.get(i).text) RemindTheme.colors.main_4 else RemindTheme.colors.white, + if(uiState.moodActivity.feelingType == feelingList.get(i).text) RemindTheme.colors.main_4 else RemindTheme.colors.white, onClick = { - viewModel.setEvent(WritingContract.Event.FeelingActivityButtonClicked( - feelingList.get(i).text - )) + viewModel.setEvent(WritingContract.Event.FeelingActivityButtonClicked(feelingList.get(i).text)) } ) } @@ -163,19 +161,11 @@ fun WritingMoodStep2FeelingScreen(navController: NavHostController, viewModel: W .padding(bottom = 32.dp), text = stringResource(id = R.string.다음), RoundedCorner = 12.dp, - backgroundColor = if(uiState.feelingType != "") RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, - textColor = if(uiState.feelingType != "") RemindTheme.colors.white else RemindTheme.colors.slate_300, + backgroundColor = if(uiState.moodActivity.feelingType != "") RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + textColor = if(uiState.moodActivity.feelingType != "") RemindTheme.colors.white else RemindTheme.colors.slate_300, verticalPadding = 13.dp, onClick = { - viewModel.setEvent(WritingContract.Event.StoreFeelingListItem( - activityData = MoodActivity( - uiState.activityId, - uiState.feelingType, - textState.value - ), - destinationRoute = Screens.Patience.Home.WritingMoodStep2Last.route, - currentRoute = Screens.Patience.Home.WritingMoodStep2Feeling.route - )) + viewModel.setEvent(WritingContract.Event.StoreFeelingListItem(textState.value)) }, textStyle = RemindTheme.typography.b2Bold ) diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt index e7635a5..6ba2bbe 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -122,11 +123,11 @@ fun WritingMoodStep2LastScreen(navController: NavHostController, viewModel: Writ text = stringResource(id = R.string.오늘의_활동은_최대_3개까지), style = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.slate_400) ) - if(uiState.MoodActivityList.size >0) { + if(uiState.writingMoodRequest.moodActivities.isNotEmpty()) { LazyColumn( - modifier = Modifier.padding(start = 20.dp, end = 20.dp, top = 70.dp), + modifier = Modifier.padding(top = 30.dp), ) { - itemsIndexed(uiState.MoodActivityList) {index, item -> + itemsIndexed(uiState.writingMoodRequest.moodActivities) {index, item -> ActivityListContainer( modifier = Modifier.padding(bottom = 10.dp), activityImage = findActivityImage(item.activityId)!!, @@ -264,7 +265,9 @@ fun PlusContainer( ) ) { Column( - modifier = modifier.padding(vertical = 13.dp), + modifier = modifier + .padding(vertical = 13.dp) + .align(Alignment.Center), verticalArrangement = Arrangement.Center, ) { Image( diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt index fcd6b12..16249e7 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt @@ -12,6 +12,7 @@ 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.layout.width import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid @@ -122,12 +123,9 @@ fun WritingMoodStep2Screen(navController: NavHostController, viewModel: WritingV ) { itemsIndexed(uiState.ActivityList) {index, item -> ImageContainerContent( - background = if(uiState.activityId != null) RemindTheme.colors.main_4 else RemindTheme.colors.white, + background = if(uiState.moodActivity.activityId != 0) RemindTheme.colors.main_4 else RemindTheme.colors.white, onClick = { - viewModel.setEvent(WritingContract.Event.ActivityButtonClicked( - item.activityId, - item.name - )) + viewModel.setEvent(WritingContract.Event.ActivityButtonClicked(item.activityId)) }, imageUrl = item.iconImage, name = item.name @@ -142,8 +140,8 @@ fun WritingMoodStep2Screen(navController: NavHostController, viewModel: WritingV .padding(bottom = 32.dp), text = stringResource(id = R.string.다음), RoundedCorner = 12.dp, - backgroundColor = if(uiState.activityId != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, - textColor = if(uiState.activityId != null) RemindTheme.colors.white else RemindTheme.colors.slate_300, + backgroundColor = if(uiState.moodActivity.activityId != 0) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, + textColor = if(uiState.moodActivity.activityId != 0) RemindTheme.colors.white else RemindTheme.colors.slate_300, verticalPadding = 13.dp, onClick = { viewModel.setEvent(WritingContract.Event.NextButtonClicked( @@ -180,7 +178,9 @@ fun ImageContainerContent( verticalArrangement = Arrangement.Center ) { GlideImage( - modifier = modifier.padding(bottom = 6.dp), + modifier = modifier + .padding(bottom = 6.dp) + .size(width = 29.dp, height = 45.dp), model = imageUrl, contentDescription = null ) diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt index 32c0831..c48c587 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController import com.example.remind.R @@ -65,12 +66,8 @@ fun WritingMoodStep3Screen(navController: NavHostController, viewModel: WritingV RemindTheme { Column ( modifier = Modifier - .fillMaxSize() .background(color = RemindTheme.colors.white) - .padding( - start = 20.dp, - end = 20.dp - ) + .padding(horizontal = 20.dp) ) { Spacer(modifier = Modifier.height(24.dp)) IconButton( @@ -91,7 +88,7 @@ fun WritingMoodStep3Screen(navController: NavHostController, viewModel: WritingV Text( modifier = Modifier.padding(top = 16.dp), text = stringResource(id = R.string.오늘_하루_감사한점_3가지), - style = RemindTheme.typography.h1Bold.copy(color = RemindTheme.colors.text) + style = RemindTheme.typography.h1Bold.copy(color = RemindTheme.colors.text, lineHeight = 31.sp) ) Text( modifier = Modifier.padding(top = 12.dp), @@ -106,14 +103,15 @@ fun WritingMoodStep3Screen(navController: NavHostController, viewModel: WritingV onTextChanged = handleTextChange, text = textState.value, roundedShape = 18.dp, - hintText = stringResource(id = R.string.일기_예시), + hintText = "Ex) 1. 아름다운 벚꽃을 볼 수 있음에 감사해요.", topPadding = 21.dp, bottomPadding = 86.dp ) Spacer(modifier = Modifier.weight(1f)) BasicButton( modifier = Modifier - .fillMaxWidth(), + .fillMaxWidth() + .padding(bottom = 32.dp), text = stringResource(id = R.string.다음), RoundedCorner = 12.dp, backgroundColor = if(textState.value != null) RemindTheme.colors.slate_100 else RemindTheme.colors.main_6, @@ -123,8 +121,6 @@ fun WritingMoodStep3Screen(navController: NavHostController, viewModel: WritingV viewModel.setEvent(WritingContract.Event.SendInfoButton( destinationRoute = Screens.Patience.Home.SplashCheering.route, currentRoute = Screens.Patience.Home.WritingMoodStep3.route, - localDate = dateValue, - detail = textState.value )) }, textStyle = RemindTheme.typography.b2Bold diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt index fec7e03..25f2b02 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt @@ -25,8 +25,13 @@ class WritingViewModel @Inject constructor( } override fun reduceState(event: WritingContract.Event) { when(event) { + //step1에서 이모티콘 눌렀을때 is WritingContract.Event.FeelingButtonClicked -> { - updateState(currentState.copy(totalFeelingType = event.feelingType)) + updateState(currentState.copy( + writingMoodRequest = currentState.writingMoodRequest.copy( + feelingType = event.feelingType + ) + )) } is WritingContract.Event.NextButtonClicked -> { navigateToRoute(event.destinationRoute, event.currentRoute, false) @@ -37,34 +42,47 @@ class WritingViewModel @Inject constructor( is WritingContract.Event.PreviousButtonClicked -> { navigateToRoute(event.destinationRoute, event.currentRoute, true) } + //step 2 활동을 선택하는 화면에서 아이콘 누르는 기능 is WritingContract.Event.ActivityButtonClicked -> { - updateState(currentState.copy(activityId = event.activityId)) - updateState(currentState.copy(activityName = event.activityName)) + updateState(currentState.copy( + moodActivity = currentState.moodActivity.copy( + activityId = event.activityId + ) + )) } -// + + //step2 활동별 무드 등록하는 step2feelingscreen is WritingContract.Event.FeelingActivityButtonClicked -> { - updateState(currentState.copy(feelingType = event.feelingType)) + updateState(currentState.copy( + moodActivity = currentState.moodActivity.copy( + feelingType = event.feelingType + ) + )) } + //활동기록 마지막 조회 페이지 가기 전 feelingscreen is WritingContract.Event.StoreFeelingListItem -> { - val newList = currentState.MoodActivityList + MoodActivity( - event.activityData.activityId, - event.activityData.detail, - event.activityData.feelingType - ) - navigateToRoute(event.destinationRoute, event.currentRoute, false) + updateState(currentState.copy( + moodActivity = currentState.moodActivity.copy( + detail = event.detail + ) + )) + val newData = currentState.moodActivity + updateState(currentState.copy( + writingMoodRequest = currentState.writingMoodRequest.copy( + moodActivities = currentState.writingMoodRequest.moodActivities + newData + ) + )) + //다시 초기화 + updateState(currentState.copy( + moodActivity = MoodActivity() + )) + navigateToRoute(Screens.Patience.Home.WritingMoodStep2Last.route, Screens.Patience.Home.WritingMoodStep2Feeling.route, false) } is WritingContract.Event.NavigateToStep2 -> { navigateToRoute(event.destinationRoute, event.currentRoute, true) } is WritingContract.Event.SendInfoButton -> { - setMoodData( - WritingMoodRequest( - detail = event.detail, - feelingType = currentState.totalFeelingType, - localDate = event.localDate, - moodActivities = currentState.MoodActivityList - ) - ) + setMoodData(currentState.writingMoodRequest) navigateToRoute(event.destinationRoute, event.currentRoute,true) } } From 83890bae52532a973f46af068f74ce8de2c7d060 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Wed, 22 May 2024 20:52:18 +0900 Subject: [PATCH 18/19] =?UTF-8?q?[feat]=20=EC=95=BD=20=EB=B3=B5=EC=9A=A9?= =?UTF-8?q?=EB=A5=A0=20=ED=99=94=EB=A9=B4=20=EA=B5=AC=ED=98=84=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 2 +- .../core/common/component/BasicBottomSheet.kt | 9 ++ .../core/common/component/IconContainer.kt | 2 +- .../response/CurrentSeriesDayResponse.kt | 10 +++ .../model/response/GetMedicineRateResponse.kt | 8 +- .../response/GetMonthlyMedicineResponse.kt | 16 ++-- .../model/response/GetPrescriptionResponse.kt | 4 +- .../data/network/service/PatientService.kt | 9 +- .../patient/PatientMedicineRepository.kt | 4 +- .../patient/PatientMedicineRepositoryImpl.kt | 4 +- .../patient/PatientMoodChartRepository.kt | 2 + .../patient/PatientMoodChartRepositoryImpl.kt | 5 ++ .../GetMonthlyMedicineUseCase.kt | 3 +- .../patience_usecase/SeriesRecordUseCase.kt | 14 ++++ .../patience/medicine/MedicineContract.kt | 10 ++- .../patience/medicine/MedicineScreen.kt | 82 +++++++++++-------- .../patience/medicine/MedicineViewModel.kt | 51 +++++++++++- .../medicine/component/MedicineCalendar.kt | 21 ++--- .../moodchart/MoodChartBottomSheet.kt | 1 + .../patience/moodchart/MoodChartContract.kt | 8 +- .../patience/moodchart/MoodChartScreen.kt | 30 ++++--- .../patience/moodchart/MoodChartViewModel.kt | 18 +++- .../patience/writing/WritingContract.kt | 2 +- .../writing/WritingMoodStep2FeelingScreen.kt | 2 +- .../writing/WritingMoodStep2LastScreen.kt | 43 +++++----- .../writing/WritingMoodStep2Screen.kt | 33 ++++---- .../writing/WritingMoodStep3Screen.kt | 6 +- .../patience/writing/WritingViewModel.kt | 9 ++ 28 files changed, 280 insertions(+), 128 deletions(-) create mode 100644 app/src/main/java/com/example/remind/data/model/response/CurrentSeriesDayResponse.kt create mode 100644 app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SeriesRecordUseCase.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d76a0b2..b1ba780 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -30,7 +30,7 @@ android:name=".app.MainActivity" android:exported="true" android:theme="@style/AppTheme" - android:windowSoftInputMode="adjustResize" + android:windowSoftInputMode="adjustPan" android:label="@string/app_name" > diff --git a/app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt b/app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt index a8f2f86..4d40c5f 100644 --- a/app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt +++ b/app/src/main/java/com/example/remind/core/common/component/BasicBottomSheet.kt @@ -2,6 +2,9 @@ package com.example.remind.core.common.component import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ModalBottomSheet @@ -11,6 +14,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.unit.dp import com.example.remind.core.designsystem.theme.RemindTheme @@ -22,6 +26,9 @@ fun BasicBottomSheet( onDismissRequest: () -> Unit, sheetContent: @Composable ColumnScope.() -> Unit ) { + val configuration = LocalConfiguration.current + val screenHeight = configuration.screenHeightDp.dp + val modalHeight = screenHeight * 0.9f ModalBottomSheet( sheetState = sheetState, onDismissRequest = onDismissRequest, @@ -32,6 +39,8 @@ fun BasicBottomSheet( ) { Column( modifier = Modifier + .fillMaxWidth() + .height(modalHeight) .clip(RoundedCornerShape(topStart = 20.dp, topEnd = 20.dp)) ) { sheetContent() diff --git a/app/src/main/java/com/example/remind/core/common/component/IconContainer.kt b/app/src/main/java/com/example/remind/core/common/component/IconContainer.kt index b644a44..c6322b3 100644 --- a/app/src/main/java/com/example/remind/core/common/component/IconContainer.kt +++ b/app/src/main/java/com/example/remind/core/common/component/IconContainer.kt @@ -34,7 +34,7 @@ fun IconContainer( horizontalAlignment = Alignment.CenterHorizontally ) { Image( - modifier = modifier + modifier = Modifier .padding( top = 18.dp, start = 15.dp, diff --git a/app/src/main/java/com/example/remind/data/model/response/CurrentSeriesDayResponse.kt b/app/src/main/java/com/example/remind/data/model/response/CurrentSeriesDayResponse.kt new file mode 100644 index 0000000..4378e5c --- /dev/null +++ b/app/src/main/java/com/example/remind/data/model/response/CurrentSeriesDayResponse.kt @@ -0,0 +1,10 @@ +package com.example.remind.data.model.response + +data class CurrentSeriesDayResponse( + val code: Int, + val `data`: CurrentSeries, + val message: String +) +data class CurrentSeries( + val currentSeriesDays: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/GetMedicineRateResponse.kt b/app/src/main/java/com/example/remind/data/model/response/GetMedicineRateResponse.kt index 1f506d5..a664ac3 100644 --- a/app/src/main/java/com/example/remind/data/model/response/GetMedicineRateResponse.kt +++ b/app/src/main/java/com/example/remind/data/model/response/GetMedicineRateResponse.kt @@ -6,8 +6,8 @@ data class GetMedicineRateResponse( val message: String ) data class Rate( - val breakfastRate: Int=0, - val dinnerRate: Int=0, - val lunchRate: Int=0, - val totalRate: Int=0 + val breakfastRate: Double=0.0, + val dinnerRate: Double=0.0, + val lunchRate: Double=0.0, + val totalRate: Double=0.0 ) diff --git a/app/src/main/java/com/example/remind/data/model/response/GetMonthlyMedicineResponse.kt b/app/src/main/java/com/example/remind/data/model/response/GetMonthlyMedicineResponse.kt index 0136db4..931f43e 100644 --- a/app/src/main/java/com/example/remind/data/model/response/GetMonthlyMedicineResponse.kt +++ b/app/src/main/java/com/example/remind/data/model/response/GetMonthlyMedicineResponse.kt @@ -1,16 +1,16 @@ package com.example.remind.data.model.response data class GetMonthlyMedicineResponse( - val code: Int, - val `data`: Monthly, - val message: String + val code: Int=0, + val `data`: Monthly = Monthly(), + val message: String="" ) data class Monthly( - val monthlyTakingMedicineDtos: List + val monthlyTakingMedicineDtos: List = emptyList() ) data class MonthlyTakingMedicineDto( - val date: String, - val needMedicine: Boolean, - val takingCount: Int, - val takingLevel: Int + val date: Int= 0, + val needMedicine: Boolean = false, + val takingCount: Int = 0, + val takingLevel: Int = 0 ) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/model/response/GetPrescriptionResponse.kt b/app/src/main/java/com/example/remind/data/model/response/GetPrescriptionResponse.kt index cb691ed..927da66 100644 --- a/app/src/main/java/com/example/remind/data/model/response/GetPrescriptionResponse.kt +++ b/app/src/main/java/com/example/remind/data/model/response/GetPrescriptionResponse.kt @@ -12,10 +12,12 @@ data class GetPrescriptionResponse( data class Prescription( val breakfastImportance: Int = 0, val dinnerImportance: Int = 0, + val etcImportance: Int = 0, val isExist: Boolean = true, val lunchImportance: Int = 0, val memo: String = "", val name: String = "", val period: Int = 0, - val prescriptionDate: String = "" + val prescriptionDate: String = "", + val prescriptionId: Int = 0 ) \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt index d9bcb4d..5aab8b0 100644 --- a/app/src/main/java/com/example/remind/data/network/service/PatientService.kt +++ b/app/src/main/java/com/example/remind/data/network/service/PatientService.kt @@ -3,10 +3,12 @@ package com.example.remind.data.network.service import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.model.request.WritingMoodRequest import com.example.remind.data.model.response.ActivityListResponse +import com.example.remind.data.model.response.CurrentSeriesDayResponse import com.example.remind.data.model.response.GetDailyMoodResponse import com.example.remind.data.model.response.GetFeelingActivityResponse import com.example.remind.data.model.response.GetFeelingPercentResponse import com.example.remind.data.model.response.GetMedicineRateResponse +import com.example.remind.data.model.response.GetMonthlyMedicineResponse import com.example.remind.data.model.response.GetPrescriptionResponse import com.example.remind.data.model.response.MedicineInfoResponse import com.example.remind.data.model.response.MedicingDailyInfoResponse @@ -77,12 +79,13 @@ interface PatientService { @Query("memberId") memberId: Int, @Query("year") year: Int, @Query("month") month: Int, - ): ApiResult + ): ApiResult - @GET("/mood") + @GET("/mood/{moodDate}") suspend fun getDailyMood( @Path("moodDate") moodDate:String ): ApiResult - + @GET("/mood/chart/series") + suspend fun getSeries(): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt index 493bddb..e58986c 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepository.kt @@ -4,10 +4,10 @@ import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.model.request.WritingMoodRequest import com.example.remind.data.model.response.ActivityListResponse import com.example.remind.data.model.response.GetMedicineRateResponse +import com.example.remind.data.model.response.GetMonthlyMedicineResponse import com.example.remind.data.model.response.GetPrescriptionResponse import com.example.remind.data.model.response.MedicingDailyInfoResponse import com.example.remind.data.model.response.MoodChartResponse -import com.example.remind.data.model.response.OnBoardingResponse import com.example.remind.data.model.response.SetMedicineInfoResponse import com.example.remind.data.model.response.WritingMoodResponse import com.example.remind.data.network.adapter.ApiResult @@ -20,5 +20,5 @@ interface PatientMedicineRepository { suspend fun getMoodChart(year: Int, month: Int, day: Int, size: Int): ApiResult suspend fun getPrescription(memberId: Int): ApiResult suspend fun getMedicineRate(memberId: Int): ApiResult - suspend fun getMonthlyMedicine(memberId: Int, year: Int, month: Int,): ApiResult + suspend fun getMonthlyMedicine(memberId: Int, year: Int, month: Int,): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt index 6e9f7ae..08e12e5 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMedicineRepositoryImpl.kt @@ -4,10 +4,10 @@ import com.example.remind.data.model.request.SetMedicineInfoRequest import com.example.remind.data.model.request.WritingMoodRequest import com.example.remind.data.model.response.ActivityListResponse import com.example.remind.data.model.response.GetMedicineRateResponse +import com.example.remind.data.model.response.GetMonthlyMedicineResponse import com.example.remind.data.model.response.GetPrescriptionResponse import com.example.remind.data.model.response.MedicingDailyInfoResponse import com.example.remind.data.model.response.MoodChartResponse -import com.example.remind.data.model.response.OnBoardingResponse import com.example.remind.data.model.response.SetMedicineInfoResponse import com.example.remind.data.model.response.WritingMoodResponse import com.example.remind.data.network.adapter.ApiResult @@ -57,7 +57,7 @@ class PatientMedicineRepositoryImpl @Inject constructor( memberId: Int, year: Int, month: Int - ): ApiResult { + ): ApiResult { return service.getMonthlyMedicine(memberId, year, month) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt index 92eb06d..12d8c9f 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepository.kt @@ -1,5 +1,6 @@ package com.example.remind.data.repository.patient +import com.example.remind.data.model.response.CurrentSeriesDayResponse import com.example.remind.data.model.response.GetDailyMoodResponse import com.example.remind.data.model.response.GetFeelingActivityResponse import com.example.remind.data.model.response.GetFeelingPercentResponse @@ -9,5 +10,6 @@ interface PatientMoodChartRepository { suspend fun getFeelingPercentChart(): ApiResult suspend fun getFeelingTypeActivity(feelingType: String): ApiResult suspend fun getMoodDaily(moodDate: String): ApiResult + suspend fun getSeriesRecord(): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt index ecf13bc..abeaa3d 100644 --- a/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt +++ b/app/src/main/java/com/example/remind/data/repository/patient/PatientMoodChartRepositoryImpl.kt @@ -1,5 +1,6 @@ package com.example.remind.data.repository.patient +import com.example.remind.data.model.response.CurrentSeriesDayResponse import com.example.remind.data.model.response.GetDailyMoodResponse import com.example.remind.data.model.response.GetFeelingActivityResponse import com.example.remind.data.model.response.GetFeelingPercentResponse @@ -21,4 +22,8 @@ class PatientMoodChartRepositoryImpl @Inject constructor( override suspend fun getMoodDaily(moodDate: String): ApiResult { return service.getDailyMood(moodDate) } + + override suspend fun getSeriesRecord(): ApiResult { + return service.getSeries() + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMonthlyMedicineUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMonthlyMedicineUseCase.kt index 8c3eeb2..6641b35 100644 --- a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMonthlyMedicineUseCase.kt +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/GetMonthlyMedicineUseCase.kt @@ -1,6 +1,7 @@ package com.example.remind.domain.usecase.patience_usecase import com.example.remind.data.model.response.GetMedicineRateResponse +import com.example.remind.data.model.response.GetMonthlyMedicineResponse import com.example.remind.data.network.adapter.ApiResult import com.example.remind.data.repository.patient.PatientMedicineRepository import javax.inject.Inject @@ -8,7 +9,7 @@ import javax.inject.Inject class GetMonthlyMedicineUseCase @Inject constructor( private val patientMedicineRepository: PatientMedicineRepository ) { - suspend operator fun invoke(memberId: Int, year: Int, month: Int,): ApiResult { + suspend operator fun invoke(memberId: Int, year: Int, month: Int,): ApiResult { return patientMedicineRepository.getMonthlyMedicine(memberId, year, month) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SeriesRecordUseCase.kt b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SeriesRecordUseCase.kt new file mode 100644 index 0000000..240062d --- /dev/null +++ b/app/src/main/java/com/example/remind/domain/usecase/patience_usecase/SeriesRecordUseCase.kt @@ -0,0 +1,14 @@ +package com.example.remind.domain.usecase.patience_usecase + +import com.example.remind.data.model.response.CurrentSeriesDayResponse +import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.repository.patient.PatientMoodChartRepository +import javax.inject.Inject + +class SeriesRecordUseCase @Inject constructor( + private val patientMoodChartRepository: PatientMoodChartRepository +) { + suspend operator fun invoke(): ApiResult { + return patientMoodChartRepository.getSeriesRecord() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt index 8b3d81c..5c252ed 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt @@ -1,22 +1,28 @@ package com.example.remind.feature.screens.patience.medicine +import android.content.Context import androidx.navigation.NavOptions import androidx.navigation.NavOptionsBuilder import com.example.remind.core.base.UiEffect import com.example.remind.core.base.UiEvent import com.example.remind.core.base.UiState +import com.example.remind.data.model.response.GetMonthlyMedicineResponse +import com.example.remind.data.model.response.Monthly import com.example.remind.data.model.response.Prescription import com.example.remind.data.model.response.Rate +import com.example.remind.feature.screens.patience.home.HomeContract class MedicineContract { data class State( val prescription: Prescription = Prescription(), val alarmDialogState: Boolean = false, - val rate: Rate = Rate() + val rate: Rate = Rate(), + val userName: String = "", + val getMonthlyMedicineResponse: GetMonthlyMedicineResponse = GetMonthlyMedicineResponse() ): UiState sealed class Event: UiEvent { - + data class moveToButtonClicked(val context: Context):Event() } sealed class Effect: UiEffect { data class NavigateTo( diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt index a7fe9b6..ac0101b 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineScreen.kt @@ -1,6 +1,7 @@ package com.example.remind.feature.screens.patience.medicine import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.gestures.scrollable import androidx.compose.foundation.layout.Arrangement @@ -26,6 +27,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle @@ -57,7 +59,7 @@ import kotlinx.coroutines.flow.collectLatest fun MedicineScreen(navController: NavHostController, viewModel: MedicineViewModel) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() val effectFlow = viewModel.effect - + val context = LocalContext.current val scrollState = rememberScrollState() LaunchedEffect(true) { effectFlow.collectLatest { effect -> @@ -75,6 +77,7 @@ fun MedicineScreen(navController: NavHostController, viewModel: MedicineViewMode Column( modifier = Modifier .fillMaxSize() + .background(color = RemindTheme.colors.white) .padding(start = 20.dp, end = 20.dp) .verticalScroll(scrollState), ) { @@ -88,22 +91,22 @@ fun MedicineScreen(navController: NavHostController, viewModel: MedicineViewMode verticalAlignment = Alignment.CenterVertically ) { Text( - text = "00님의 약 처방", + text = "${uiState.userName}님의 약 처방", style = RemindTheme.typography.b2Bold.copy(color = RemindTheme.colors.text) ) Spacer(modifier = Modifier.weight(1f)) Text( - text = "처방날짜 들어갈자리", + text = uiState.prescription.prescriptionDate, style = RemindTheme.typography.c1Medium.copy(color = RemindTheme.colors.text) ) Text( modifier = Modifier.padding(start = 6.dp), - text = "(몇일분 처방)", + text = "(${uiState.prescription.period}일분 처방)", style = RemindTheme.typography.c1Medium.copy(color = RemindTheme.colors.grayscale_3) ) } CurrentMedicineContainer( - modifier = Modifier.padding(top = 7.dp), + modifier = Modifier.padding(top = 7.dp, bottom = 8.dp), prescription = uiState.prescription ) BasicButton( @@ -113,7 +116,9 @@ fun MedicineScreen(navController: NavHostController, viewModel: MedicineViewMode backgroundColor = RemindTheme.colors.main_6, textColor = RemindTheme.colors.white, verticalPadding = 12.dp, - onClick = { }, + onClick = { + viewModel.setEvent(MedicineContract.Event.moveToButtonClicked(context)) + }, textStyle = RemindTheme.typography.b2Bold ) Text( @@ -122,7 +127,7 @@ fun MedicineScreen(navController: NavHostController, viewModel: MedicineViewMode style = RemindTheme.typography.b2Bold.copy(color = RemindTheme.colors.text) ) MedicineRateContainer( - modifier = Modifier.padding(top = 6.dp), + modifier = Modifier.padding(top = 6.dp, bottom = 10.dp), rate = uiState.rate ) Box( @@ -140,13 +145,16 @@ fun MedicineScreen(navController: NavHostController, viewModel: MedicineViewMode verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { - CalendarHeader(modifier = Modifier.padding(top = 9.dp)) - MedicineCalendar() - Image( - modifier = Modifier.padding(end = 15.dp, bottom = 24.dp), - painter = painterResource(id = R.drawable.ex_info), - contentDescription = null - ) + CalendarHeader(modifier = Modifier.padding(top = 9.dp, bottom = 9.dp)) + MedicineCalendar(monthData = uiState.getMonthlyMedicineResponse.data.monthlyTakingMedicineDtos) + Row { + Spacer(modifier = Modifier.weight(1f)) + Image( + modifier = Modifier.padding(end = 15.dp, bottom = 24.dp), + painter = painterResource(id = R.drawable.ex_info), + contentDescription = null + ) + } } } } @@ -196,10 +204,12 @@ fun CurrentMedicineContainer( ) ) { Column( - modifier = modifier.padding(vertical = 20.dp) + modifier = modifier.padding(horizontal = 19.dp) ) { Row( - modifier = modifier.padding(top = 14.dp), + modifier = modifier + .fillMaxWidth() + .padding(top = 14.dp), horizontalArrangement = Arrangement.SpaceEvenly ) { TimeMedicineList( @@ -214,21 +224,22 @@ fun CurrentMedicineContainer( time = stringResource(id = R.string.저녁), importance = prescription.dinnerImportance.toFloat() ) - //바꿔야함 TimeMedicineList( time = stringResource(id = R.string.비상용), - importance = prescription.breakfastImportance.toFloat() - ) - } - Box( - modifier = modifier.padding(top = 20.dp, bottom = 11.dp), - ) { - Text( - modifier = modifier.padding(start = 14.dp, top = 3.dp, bottom = 3.dp), - text = prescription.memo, - style = RemindTheme.typography.c2Regular.copy(color = RemindTheme.colors.slate_700) + importance = prescription.etcImportance.toFloat() ) } + Text( + modifier = modifier + .fillMaxWidth() + .background( + color = RemindTheme.colors.main_2, + shape = RoundedCornerShape(20.dp) + ) + .padding(start = 14.dp, top = 3.dp, bottom = 3.dp), + text = prescription.memo, + style = RemindTheme.typography.c2Regular.copy(color = RemindTheme.colors.slate_700) + ) } } } @@ -240,11 +251,12 @@ fun TimeMedicineList( importance: Float, ) { Column( - verticalArrangement = Arrangement.Center + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally ) { Text( modifier = modifier.padding(bottom = 7.dp), - text = time, + text = time, style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.main_6) ) StarRatingBar( @@ -274,7 +286,7 @@ fun MedicineRateContainer( ) { Row { Text( - text = "${rate.totalRate}%", + text = String.format("%.1f", rate.totalRate), style = RemindTheme.typography.h1Bold.copy(color= RemindTheme.colors.main_6) ) Text( @@ -284,7 +296,9 @@ fun MedicineRateContainer( ) } Row( - modifier = modifier.padding(top = 9.dp, bottom = 18.dp) + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceEvenly + ) { Text( text = "아침: ", @@ -292,7 +306,7 @@ fun MedicineRateContainer( ) Text( modifier = modifier.padding(start = 4.dp), - text = "${rate.breakfastRate}%", + text = String.format("%.1f", rate.breakfastRate), style = RemindTheme.typography.c2Medium.copy(color= RemindTheme.colors.main_6) ) Text( @@ -301,7 +315,7 @@ fun MedicineRateContainer( ) Text( modifier = modifier.padding(start = 4.dp), - text = "${rate.lunchRate}%", + text = String.format("%.1f", rate.lunchRate), style = RemindTheme.typography.c2Medium.copy(color= RemindTheme.colors.main_6) ) Text( @@ -310,7 +324,7 @@ fun MedicineRateContainer( ) Text( modifier = modifier.padding(start = 4.dp), - text = "${rate.dinnerRate}%", + text = String.format("%.1f", rate.dinnerRate), style = RemindTheme.typography.c2Medium.copy(color= RemindTheme.colors.main_6) ) } diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt index 6188b8b..2685051 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt @@ -1,13 +1,18 @@ package com.example.remind.feature.screens.patience.medicine import androidx.lifecycle.viewModelScope +import androidx.navigation.navOptions +import com.example.remind.app.Screens import com.example.remind.core.base.BaseViewModel import com.example.remind.data.network.adapter.ApiResult +import com.example.remind.data.network.interceptor.TokenManager import com.example.remind.domain.usecase.patience_usecase.GetMedicineRateUseCase import com.example.remind.domain.usecase.patience_usecase.GetMonthlyMedicineUseCase import com.example.remind.domain.usecase.patience_usecase.PrescriptionUseCase +import com.example.remind.feature.screens.patience.home.HomeContract import com.example.remind.feature.screens.patience.moodchart.MoodChartContract import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import javax.inject.Inject @@ -15,22 +20,33 @@ import javax.inject.Inject class MedicineViewModel @Inject constructor( private val prescriptionUseCase: PrescriptionUseCase, private val getMonthlyMedicineUseCase: GetMonthlyMedicineUseCase, - private val getMedicineRateUseCase: GetMedicineRateUseCase + private val getMedicineRateUseCase: GetMedicineRateUseCase, + private val tokenManager: TokenManager ): BaseViewModel( initialState = MedicineContract.State() ) { init { viewModelScope.launch { + val userName = tokenManager.getUserName().first() + updateState(currentState.copy(userName = userName ?: "김말랑")) getPrescription() getMedicineRate() + getMonthMedicine() } } override fun reduceState(event: MedicineContract.Event) { -// when(event) { -// -// } + when(event) { + is MedicineContract.Event.moveToButtonClicked -> { + navigateToRoute( + destination = Screens.Patience.Medicine.AlarmSetting.route, + current = Screens.Patience.Medicine.route, + inclusiveData = false + ) + } + } } + private fun getPrescription() { viewModelScope.launch { val result = prescriptionUseCase.invoke(0) @@ -58,4 +74,31 @@ class MedicineViewModel @Inject constructor( } } + private fun getMonthMedicine() { + viewModelScope.launch { + val result = getMonthlyMedicineUseCase.invoke(0, 2024, 5) + when(result) { + is ApiResult.Success -> { + updateState(currentState.copy( + getMonthlyMedicineResponse = result.data + )) + } + else -> {} + } + } + } + + fun navigateToRoute(destination: String, current: String, inclusiveData: Boolean) { + postEffect( + MedicineContract.Effect.NavigateTo( + destinaton = destination, + navOptions = navOptions { + popUpTo(current) { + inclusive = inclusiveData + } + } + ) + ) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/component/MedicineCalendar.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/component/MedicineCalendar.kt index 875f498..b08d499 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/component/MedicineCalendar.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/component/MedicineCalendar.kt @@ -14,16 +14,16 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.example.remind.core.designsystem.theme.RemindTheme +import com.example.remind.data.model.response.MonthlyTakingMedicineDto import java.time.LocalDate import java.time.YearMonth @Composable fun MedicineCalendar( - modifier: Modifier = Modifier + modifier: Modifier = Modifier, + monthData: List ) { val year = LocalDate.now().year val month = LocalDate.now().monthValue @@ -67,12 +67,19 @@ fun MedicineCalendar( .height(40.dp) ) } else { + val date = monthData.find {it.date == dayCounter} + val background = when { + date?.takingLevel == 0 -> RemindTheme.colors.sub_2 + date?.takingLevel == 1 -> RemindTheme.colors.main_3 + date?.takingLevel == 2 -> RemindTheme.colors.main_6 + else -> RemindTheme.colors.white + } Box( modifier = Modifier .weight(1f) .padding(13.dp) .height(30.dp) - .background(shape = CircleShape, color = RemindTheme.colors.main_6), + .background(shape = CircleShape, color = background), contentAlignment = Alignment.Center ) { Text( @@ -88,9 +95,3 @@ fun MedicineCalendar( } } - -@Preview(showBackground = true) -@Composable -fun CalendarPreview() { - MedicineCalendar() -} diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt index 5bd2246..58d3d6d 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartBottomSheet.kt @@ -9,6 +9,7 @@ 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.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt index 2f026c4..5cc266f 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartContract.kt @@ -8,19 +8,19 @@ import com.example.remind.core.base.UiState import com.example.remind.data.model.response.DailyTakingMedicineList import com.example.remind.data.model.response.Data import com.example.remind.data.model.response.Mood -import com.example.remind.data.model.response.MoodChartResponse import com.example.remind.data.model.response.PercentList -import com.example.remind.feature.screens.patience.home.HomeContract +import java.time.LocalDate class MoodChartContract { data class State( val moodChartData: Mood = Mood(true, emptyList()), val xAxisData: List = emptyList(), val yAxisData: List = emptyList(), - val date: String = "", + val date: String = LocalDate.now().dayOfMonth.toString(), val dailyMood: Data = Data(), val feelingTotalPerCent: List = emptyList(), - val dailyMedicine: List = emptyList() + val dailyMedicine: List = emptyList(), + val currentSeriesDay: Int = 0 ): UiState sealed class Event: UiEvent { diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt index 9aca41f..3994837 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartScreen.kt @@ -21,7 +21,6 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text @@ -29,7 +28,10 @@ import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush @@ -37,7 +39,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController @@ -50,7 +51,6 @@ import com.example.remind.core.designsystem.theme.RemindTheme import com.example.remind.data.model.graphScoreModel import com.example.remind.data.model.response.FeelingActivity import com.example.remind.data.repository.CalendarDataSource -import com.example.remind.feature.screens.patience.home.HomeContract import com.example.remind.feature.screens.patience.moodchart.component.FeelingPercentGraph import com.jaikeerthick.composable_graphs.composables.line.LineGraph import com.jaikeerthick.composable_graphs.composables.line.model.LineData @@ -67,7 +67,11 @@ import java.time.LocalDate fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewModel) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() val effectFlow = viewModel.effect + val sheetState = rememberModalBottomSheetState() + var isSheetOpen by rememberSaveable { + mutableStateOf(false) + } val coroutineScope = rememberCoroutineScope() val scrollState = rememberScrollState() val graphYaxisList = listOf( @@ -77,13 +81,15 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod graphScoreModel(25, R.drawable.ic_bad), graphScoreModel(0, R.drawable.ic_terrible), ) - MoodChartBottomSheet( - viewModel = viewModel, - sheetState = sheetState, - onDismissRequest = { - coroutineScope.launch { sheetState.hide() } - } - ) + if(isSheetOpen == true) { + MoodChartBottomSheet( + viewModel = viewModel, + sheetState = sheetState, + onDismissRequest = { + isSheetOpen = false + } + ) + } LaunchedEffect(true) { effectFlow.collectLatest { effect -> when(effect) { @@ -112,7 +118,7 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod BasicTextButton( modifier = Modifier.fillMaxWidth(), backgroundColor = RemindTheme.colors.slate_600, - text = "17일째 연속으로 기록 중이에요! 파이팅:)", + text = "${uiState.currentSeriesDay}일째 연속으로 기록 중이에요! 파이팅:)", textColor = RemindTheme.colors.slate_100, onClick = { }, verticalPadding = 7.dp, @@ -132,9 +138,11 @@ fun MoodChartScreen(navController: NavHostController, viewModel:MoodChartViewMod textColor = RemindTheme.colors.white, verticalPadding = 18.dp, onClick = { + isSheetOpen = true viewModel.setEvent(MoodChartContract.Event.ClickToBottomSheet( "2024-05-${uiState.date}" )) + }, textStyle = RemindTheme.typography.b3Bold ) diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt index 6baf20e..540c3f0 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt @@ -8,6 +8,7 @@ import com.example.remind.domain.usecase.patience_usecase.GetFeelingPercentUseCa import com.example.remind.domain.usecase.patience_usecase.GetMoodChartUseCase import com.example.remind.domain.usecase.patience_usecase.GetMoodDailyUseCase import com.example.remind.domain.usecase.patience_usecase.PatientMedicineDailyUseCase +import com.example.remind.domain.usecase.patience_usecase.SeriesRecordUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import java.time.LocalDate @@ -19,7 +20,8 @@ class MoodChartViewModel @Inject constructor( private val getFeelingPercentUseCase: GetFeelingPercentUseCase, private val getFeelingActivityUseCase: GetFeelingActivityUseCase, private val getMoodDailyUseCase: GetMoodDailyUseCase, - private val patientMedicineDailyUseCase: PatientMedicineDailyUseCase + private val patientMedicineDailyUseCase: PatientMedicineDailyUseCase, + private val seriesRecordUseCase: SeriesRecordUseCase ): BaseViewModel( initialState = MoodChartContract.State() ) { @@ -30,6 +32,8 @@ class MoodChartViewModel @Inject constructor( viewModelScope.launch { getMoodChartData(year, month, date-3) getFeelingPerCent() + getSeriesRecord() + } } override fun reduceState(event: MoodChartContract.Event) { @@ -105,6 +109,18 @@ class MoodChartViewModel @Inject constructor( } } + private fun getSeriesRecord() { + viewModelScope.launch { + val result = seriesRecordUseCase.invoke() + when(result) { + is ApiResult.Success -> { + updateState(currentState.copy(currentSeriesDay = result.data.data.currentSeriesDays)) + } + else -> {} + } + } + } + fun setToastMessage(text: String) { diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt index 0a600e8..3f6ff8b 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingContract.kt @@ -28,7 +28,7 @@ class WritingContract { data class StoreFeelingListItem(val detail: String): Event() data class NavigateToHome(val context: Context): Event() data class NavigateToStep2(val destinationRoute: String, val currentRoute: String): Event() - data class SendInfoButton(val destinationRoute: String, val currentRoute: String): Event() + data class SendInfoButton(val destinationRoute: String, val currentRoute: String, val detail: String, val localDate: String): Event() } sealed class Effect: UiEffect { diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt index 7133163..f6f5b81 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2FeelingScreen.kt @@ -111,7 +111,7 @@ fun WritingMoodStep2FeelingScreen(navController: NavHostController, viewModel: W Spacer(modifier = Modifier.height(7.dp)) Box( modifier = Modifier - .background(color = RemindTheme.colors.white) + .fillMaxWidth() .border( width = 1.dp, shape = RoundedCornerShape(18.dp), diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt index 6ba2bbe..513d57e 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2LastScreen.kt @@ -50,7 +50,6 @@ import kotlinx.coroutines.flow.collectLatest fun WritingMoodStep2LastScreen(navController: NavHostController, viewModel: WritingViewModel) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() val effectFlow = viewModel.effect - val scrollState = rememberScrollState() val feelingList = listOf( FeelingScoreModel(R.drawable.ic_verygood, "정말 좋음", "VERY_GOOD", "기분이 정말 좋았어요!"), @@ -90,7 +89,6 @@ fun WritingMoodStep2LastScreen(navController: NavHostController, viewModel: Writ Column( modifier = Modifier .fillMaxSize() - .verticalScroll(scrollState) .background(color = RemindTheme.colors.white) .padding(horizontal = 20.dp) ) { @@ -143,8 +141,8 @@ fun WritingMoodStep2LastScreen(navController: NavHostController, viewModel: Writ modifier = Modifier.padding(top = 10.dp), onClick = { viewModel.setEvent(WritingContract.Event.NavigateToStep2( - Screens.Patience.Home.WritingMoodStep2Last.route, - Screens.Patience.Home.WritingMoodStep2.route + Screens.Patience.Home.WritingMoodStep2.route, + Screens.Patience.Home.WritingMoodStep2Last.route )) } ) @@ -192,43 +190,45 @@ fun ActivityListContainer( .background(color = RemindTheme.colors.white, shape = RoundedCornerShape(8.dp)) ) { Row( - modifier = modifier.padding(horizontal = 20.dp) + modifier = Modifier.padding(horizontal = 20.dp), ) { Column( - modifier = modifier.padding(top = 6.dp, bottom = 13.dp), - verticalArrangement = Arrangement.Center + modifier = Modifier.padding(top = 6.dp, bottom = 13.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally ) { GlideImage( - modifier = modifier.padding(bottom = 6.dp), + modifier = Modifier.padding(bottom = 6.dp), model = activityImage, contentDescription = null ) Text( - modifier = modifier - .padding(horizontal = 20.dp, vertical = 2.5.dp) + modifier = Modifier .background( color = RemindTheme.colors.main_2, shape = RoundedCornerShape(18.dp) - ), + ) + .padding(horizontal = 20.dp, vertical = 2.5.dp), text = activityText, style = RemindTheme.typography.c2Medium.copy(color = RemindTheme.colors.text) ) } Column( - modifier = modifier.padding(start= 43.dp), + modifier = Modifier.padding(start= 43.dp, top = 6.dp), verticalArrangement = Arrangement.Center ) { Row( + modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Start, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Image( - modifier = modifier.size(width = 15.dp, height = 21.dp), + modifier = Modifier.size(width = 15.dp, height = 21.dp), painter = painterResource(id = moodImage), contentDescription = null ) Text( - modifier = modifier + modifier = Modifier .padding(start = 3.dp, bottom = 6.dp), text = moodDescription, style = RemindTheme.typography.b3Regular.copy(color = RemindTheme.colors.slate_600) @@ -243,7 +243,6 @@ fun ActivityListContainer( } } - @Composable fun PlusContainer( modifier: Modifier = Modifier, @@ -262,13 +261,15 @@ fun PlusContainer( onClick = onClick, interactionSource = remember { MutableInteractionSource() }, indication = null - ) + ), + contentAlignment = Alignment.Center ) { Column( modifier = modifier - .padding(vertical = 13.dp) - .align(Alignment.Center), + .fillMaxWidth() + .padding(vertical = 13.dp), verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, ) { Image( painter = painterResource(id = R.drawable.ic_plus), @@ -277,8 +278,8 @@ fun PlusContainer( Text( modifier = modifier.padding(top = 6.dp), text = stringResource(id = R.string.활동_추가하기), - style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.white) + style = RemindTheme.typography.c1Bold.copy(color = RemindTheme.colors.main_6) ) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt index 16249e7..8ced3cf 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep2Screen.kt @@ -2,6 +2,7 @@ package com.example.remind.feature.screens.patience.writing import android.widget.Toast import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -11,6 +12,7 @@ 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.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width @@ -24,6 +26,7 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext @@ -68,10 +71,7 @@ fun WritingMoodStep2Screen(navController: NavHostController, viewModel: WritingV modifier = Modifier .fillMaxSize() .background(color = RemindTheme.colors.white) - .padding( - start = 20.dp, - end = 20.dp - ) + .padding(horizontal = 20.dp) ) { Spacer(modifier = Modifier.height(24.dp)) IconButton( @@ -116,14 +116,20 @@ fun WritingMoodStep2Screen(navController: NavHostController, viewModel: WritingV ) } Box( - modifier = Modifier.fillMaxWidth() + modifier = Modifier + .fillMaxWidth() + .heightIn(min = 170.dp, max = 180.dp) + .border(width = 1.dp, color = RemindTheme.colors.grayscale_1, shape = RoundedCornerShape(18.dp)) ) { LazyHorizontalGrid( + modifier = Modifier + .padding(horizontal = 20.dp, vertical = 8.dp) + .align(Alignment.Center), rows = GridCells.Fixed(2) ) { itemsIndexed(uiState.ActivityList) {index, item -> ImageContainerContent( - background = if(uiState.moodActivity.activityId != 0) RemindTheme.colors.main_4 else RemindTheme.colors.white, + background = if(uiState.moodActivity.activityId == item.activityId) RemindTheme.colors.main_4 else RemindTheme.colors.white, onClick = { viewModel.setEvent(WritingContract.Event.ActivityButtonClicked(item.activityId)) }, @@ -165,20 +171,19 @@ fun ImageContainerContent( name: String ) { Box( - modifier = modifier - .fillMaxWidth() + modifier = Modifier .background(color = background, shape = RoundedCornerShape(12.dp)) - .clickable( - onClick = onClick - ) + .clickable(onClick = onClick) + .height(80.dp) ) { Column( - modifier = modifier + modifier = Modifier .padding(vertical = 8.dp, horizontal = 10.dp), - verticalArrangement = Arrangement.Center + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally ) { GlideImage( - modifier = modifier + modifier = Modifier .padding(bottom = 6.dp) .size(width = 29.dp, height = 45.dp), model = imageUrl, diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt index c48c587..640637b 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingMoodStep3Screen.kt @@ -56,7 +56,7 @@ fun WritingMoodStep3Screen(navController: NavHostController, viewModel: WritingV } } val year = LocalDate.now().year - val month = LocalDate.now().monthValue + val month = String.format("%02d", LocalDate.now().monthValue) val date = LocalDate.now().dayOfMonth val dateValue = "${year}-${month}-${date}" val textState = remember { mutableStateOf("") } @@ -114,11 +114,13 @@ fun WritingMoodStep3Screen(navController: NavHostController, viewModel: WritingV .padding(bottom = 32.dp), text = stringResource(id = R.string.다음), RoundedCorner = 12.dp, - backgroundColor = if(textState.value != null) RemindTheme.colors.slate_100 else RemindTheme.colors.main_6, + backgroundColor = if(textState.value != null) RemindTheme.colors.main_6 else RemindTheme.colors.slate_100, textColor = if(textState.value != null) RemindTheme.colors.white else RemindTheme.colors.slate_300, verticalPadding = 13.dp, onClick = { viewModel.setEvent(WritingContract.Event.SendInfoButton( + detail = textState.value, + localDate = dateValue, destinationRoute = Screens.Patience.Home.SplashCheering.route, currentRoute = Screens.Patience.Home.WritingMoodStep3.route, )) diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt index 25f2b02..7236429 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/writing/WritingViewModel.kt @@ -82,8 +82,17 @@ class WritingViewModel @Inject constructor( navigateToRoute(event.destinationRoute, event.currentRoute, true) } is WritingContract.Event.SendInfoButton -> { + updateState(currentState.copy( + writingMoodRequest = currentState.writingMoodRequest.copy( + localDate = event.localDate, + detail = event.detail + ) + )) setMoodData(currentState.writingMoodRequest) navigateToRoute(event.destinationRoute, event.currentRoute,true) + updateState(currentState.copy( + writingMoodRequest = WritingMoodRequest() + )) } } } From d2b70c81cbc5513338556942797123c2f5d90109 Mon Sep 17 00:00:00 2001 From: seunghee17 Date: Wed, 22 May 2024 23:11:50 +0900 Subject: [PATCH 19/19] =?UTF-8?q?[feat]=20=EC=95=8C=EB=9E=8C=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=ED=99=94=EB=A9=B4=20=EA=B5=AC=ED=98=84=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../screens/patience/home/HomeViewModel.kt | 10 +++ .../screens/patience/medicine/AlarmDialog.kt | 75 +++++++++++-------- .../patience/medicine/AlarmSettingScreen.kt | 21 +++++- .../patience/medicine/MedicineContract.kt | 2 + .../patience/medicine/MedicineViewModel.kt | 6 ++ .../screens/patience/medicine/TimePicker.kt | 32 ++++---- .../patience/moodchart/MoodChartViewModel.kt | 2 +- app/src/main/res/drawable/ex_alarm.xml | 29 +++++++ 8 files changed, 127 insertions(+), 50 deletions(-) create mode 100644 app/src/main/res/drawable/ex_alarm.xml diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt index a50a94e..b1a81f8 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/home/HomeViewModel.kt @@ -12,6 +12,8 @@ import com.example.remind.domain.usecase.patience_usecase.PatientMedicineDailyUs import com.example.remind.domain.usecase.patience_usecase.SetMedicineInfoUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch +import java.time.LocalDate +import java.time.format.DateTimeFormatter import javax.inject.Inject @HiltViewModel class HomeViewModel @Inject constructor( @@ -20,6 +22,14 @@ class HomeViewModel @Inject constructor( ): BaseViewModel( initialState = HomeContract.State() ) { + var year = LocalDate.now().year + var month = String.format("%02d", LocalDate.now().monthValue) + var date = LocalDate.now().dayOfMonth + init { + viewModelScope.launch { + getMedicineDaily(0,"${year}-${month}-${date}") + } + } override fun reduceState(event: HomeContract.Event) { when(event) { is HomeContract.Event.WritingButtonClicked -> { diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmDialog.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmDialog.kt index 3f1b239..09fe33c 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmDialog.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmDialog.kt @@ -33,6 +33,8 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.example.remind.R +import com.example.remind.core.common.component.BasicButton +import com.example.remind.core.common.component.BasicDialog import com.example.remind.core.designsystem.theme.RemindTheme import java.text.DecimalFormat import java.time.LocalTime @@ -41,17 +43,22 @@ import java.time.LocalTime fun AlarmDialog ( modifier: Modifier = Modifier, onDismissClick: () -> Unit, - onConfirmClick: () -> Unit, showDialog:Boolean, ) { - + BasicDialog( + popupContent = { + AlarmContent( + onDismissClick = onDismissClick, + ) + }, + showDialog = showDialog + ) } @Composable fun AlarmContent( modifier: Modifier = Modifier, onDismissClick: () -> Unit, - onConfirmClick: () -> Unit, ) { Box( modifier = modifier @@ -61,31 +68,38 @@ fun AlarmContent( shape = RoundedCornerShape(10.dp) ) ) { - Text( - modifier = Modifier - .align(Alignment.TopCenter) - .padding(top = 9.13.dp), - textAlign = TextAlign.Center, - text = stringResource(id = R.string.알림_추가), - style = RemindTheme.typography.b1Bold.copy(color = RemindTheme.colors.text) - ) + Column { + Row{ + Text( + modifier = Modifier + .padding(top = 9.13.dp), + textAlign = TextAlign.Center, + text = stringResource(id = R.string.알림_추가), + style = RemindTheme.typography.b1Bold.copy(color = RemindTheme.colors.text) + ) - Icon( - modifier = modifier - .align(Alignment.TopEnd) - .padding(top = 8.83.dp, end = 11.dp) - .clickable(onClick = onDismissClick), - painter = painterResource(id = R.drawable.ic_close), - tint = RemindTheme.colors.icon, - contentDescription = null - ) + Icon( + modifier = modifier + .padding(top = 8.83.dp, end = 11.dp) + .clickable(onClick = onDismissClick), + painter = painterResource(id = R.drawable.ic_close), + tint = RemindTheme.colors.icon, + contentDescription = null + ) + } + CustomTimePicker( + onTimeSelected = {}, + onDismissClick = onDismissClick + ) + } } } @Composable fun CustomTimePicker( initialTime: LocalTime = LocalTime.now(), - onTimeSelected: (LocalTime) -> Unit + onTimeSelected: (LocalTime) -> Unit, + onDismissClick: () -> Unit ) { var selectedHour by remember { mutableStateOf(if (initialTime.hour % 12 == 0) 12 else initialTime.hour % 12) } var selectedMinute by remember { mutableStateOf(initialTime.minute) } @@ -121,16 +135,15 @@ fun CustomTimePicker( } Spacer(modifier = Modifier.height(16.dp)) - Button(onClick = { - val hour24 = if (isAM) { - if (selectedHour == 12) 0 else selectedHour - } else { - if (selectedHour == 12) 12 else selectedHour + 12 - } - onTimeSelected(LocalTime.of(hour24, selectedMinute)) - }) { - androidx.compose.material3.Text("Select Time") - } + BasicButton( + text = stringResource(id = R.string.완료), + RoundedCorner = 12.dp, + backgroundColor = RemindTheme.colors.main_6, + textColor = RemindTheme.colors.white, + verticalPadding = 13.dp, + onClick = onDismissClick, + textStyle = RemindTheme.typography.c3Bold + ) } } diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmSettingScreen.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmSettingScreen.kt index 5a6b0be..bad0b64 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmSettingScreen.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/AlarmSettingScreen.kt @@ -1,5 +1,6 @@ package com.example.remind.feature.screens.patience.medicine +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -20,6 +21,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController @@ -47,6 +49,12 @@ fun AlarmSettingScreen( } } } + if(uiState.alarmDialogState) { + AlarmDialog( + onDismissClick = { viewModel.setEvent(MedicineContract.Event.dismissDialog) }, + showDialog = uiState.alarmDialogState + ) + } RemindTheme { Column( modifier = Modifier @@ -55,7 +63,9 @@ fun AlarmSettingScreen( .verticalScroll(scrollState) ) { Row( - modifier = Modifier.padding(start = 26.dp, top = 24.dp), + modifier = Modifier + .fillMaxWidth() + .padding(start = 26.dp, top = 24.dp), verticalAlignment = Alignment.CenterVertically ) { IconButton( @@ -67,6 +77,8 @@ fun AlarmSettingScreen( ) } Text( + modifier = Modifier.weight(1f), + textAlign = TextAlign.Center, text = "약 복용 알림 설정", style = RemindTheme.typography.h2Bold.copy(color = RemindTheme.colors.text) ) @@ -88,7 +100,7 @@ fun AlarmSettingScreen( textColor = RemindTheme.colors.white, verticalPadding = 5.dp, onClick = { - //다이얼로그 동작 + viewModel.setEvent(MedicineContract.Event.popDialog) }, textStyle = RemindTheme.typography.c1Medium ) @@ -99,6 +111,11 @@ fun AlarmSettingScreen( text = "알림을 통해 복용 시간을 놓치지 말아요!", style = RemindTheme.typography.c1Medium.copy(color = RemindTheme.colors.grayscale_3) ) + Image( + modifier = Modifier.fillMaxWidth(), + painter = painterResource(id = R.drawable.ex_alarm), + contentDescription = null + ) } } } diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt index 5c252ed..06eb06e 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineContract.kt @@ -23,6 +23,8 @@ class MedicineContract { sealed class Event: UiEvent { data class moveToButtonClicked(val context: Context):Event() + object popDialog:Event() + object dismissDialog: Event() } sealed class Effect: UiEffect { data class NavigateTo( diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt index 2685051..286b64f 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/MedicineViewModel.kt @@ -43,6 +43,12 @@ class MedicineViewModel @Inject constructor( inclusiveData = false ) } + is MedicineContract.Event.popDialog -> { + updateState(currentState.copy(alarmDialogState = true)) + } + is MedicineContract.Event.dismissDialog -> { + updateState(currentState.copy(alarmDialogState = false)) + } } } diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/TimePicker.kt b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/TimePicker.kt index 03d4153..09d6963 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/medicine/TimePicker.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/medicine/TimePicker.kt @@ -37,19 +37,19 @@ fun TimePicker( } } -@Preview(showBackground = true) -@Composable -fun TimePickerExample() { - var selectedTime by remember { mutableStateOf(null) } - - CustomTimePicker( - initialTime = selectedTime ?: LocalTime.now(), - onTimeSelected = { time -> - selectedTime = time - } - ) - - selectedTime?.let { - Text("Selected Time: ${it.hour % 12}:${it.minute} ${if (it.hour < 12) "AM" else "PM"}") - } -} +//@Preview(showBackground = true) +//@Composable +//fun TimePickerExample() { +// var selectedTime by remember { mutableStateOf(null) } +// +// CustomTimePicker( +// initialTime = selectedTime ?: LocalTime.now(), +// onTimeSelected = { time -> +// selectedTime = time +// } +// ) +// +// selectedTime?.let { +// Text("Selected Time: ${it.hour % 12}:${it.minute} ${if (it.hour < 12) "AM" else "PM"}") +// } +//} diff --git a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt index 540c3f0..3e9bc7a 100644 --- a/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt +++ b/app/src/main/java/com/example/remind/feature/screens/patience/moodchart/MoodChartViewModel.kt @@ -30,7 +30,7 @@ class MoodChartViewModel @Inject constructor( val date = LocalDate.now().dayOfMonth init { viewModelScope.launch { - getMoodChartData(year, month, date-3) + getMoodChartData(year, month, date-6) getFeelingPerCent() getSeriesRecord() diff --git a/app/src/main/res/drawable/ex_alarm.xml b/app/src/main/res/drawable/ex_alarm.xml new file mode 100644 index 0000000..f1f2df6 --- /dev/null +++ b/app/src/main/res/drawable/ex_alarm.xml @@ -0,0 +1,29 @@ + + + + + + +