Skip to content

Commit

Permalink
Merge pull request #76 from SOPT-all/feat/#59-user-info-update-api
Browse files Browse the repository at this point in the history
[Feat/#59] user info update api
  • Loading branch information
hwidung authored Jan 23, 2025
2 parents 23bf72e + 5c90d13 commit 061707f
Show file tree
Hide file tree
Showing 26 changed files with 392 additions and 70 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.memento.data.datasource

import org.memento.data.dto.BaseResponse
import org.memento.data.dto.request.RequestUserInfoUpdateDto

interface UserInfoDataSource {
suspend fun fetchUserInfo(requestUserInfo: RequestUserInfoUpdateDto): BaseResponse<Unit>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.memento.data.datasourceimpl

import org.memento.data.datasource.UserInfoDataSource
import org.memento.data.dto.BaseResponse
import org.memento.data.dto.request.RequestUserInfoUpdateDto
import org.memento.data.service.UserInfoUpdateService
import javax.inject.Inject

class UserDataSourceImpl
@Inject
constructor(
private val userService: UserInfoUpdateService,
) : UserInfoDataSource {
override suspend fun fetchUserInfo(requestUserInfo: RequestUserInfoUpdateDto): BaseResponse<Unit> = userService.fetchUserInfo(requestUserInfo)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.memento.data.dto.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class RequestUserInfoUpdateDto(
@SerialName("wakeUpTime")
val wakeUpTime: String,
@SerialName("windDownTime")
val windDownTime: String,
@SerialName("job")
val job: String,
@SerialName("jobOtherDetail")
val jobOtherDetail: String? = null,
@SerialName("isStressedUnorganizedSchedule")
val isStressedUnorganizedSchedule: Boolean,
@SerialName("isForgetImportantThings")
val isForgetImportantThings: Boolean,
@SerialName("isPreferReminder")
val isPreferReminder: Boolean,
@SerialName("isImportantBreaks")
val isImportantBreaks: Boolean,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.memento.data.mapper.toData

import org.memento.data.dto.request.RequestUserInfoUpdateDto
import org.memento.domain.entity.UserInfo

fun UserInfo.toData(): RequestUserInfoUpdateDto =
RequestUserInfoUpdateDto(
wakeUpTime = wakeUpTime,
windDownTime = windDownTime,
job = job,
jobOtherDetail = jobOtherDetail,
isStressedUnorganizedSchedule = isStressedUnorganizedSchedule,
isForgetImportantThings = isForgetImportantThings,
isPreferReminder = isPreferReminder,
isImportantBreaks = isImportantBreaks,
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package org.memento.data.mapper.toDomain

import org.memento.data.dto.response.ResponseLoginDto
import org.memento.domain.entity.UserInfo
import org.memento.domain.entity.LoginInfo

fun ResponseLoginDto.toUserInfo(): UserInfo =
UserInfo(
fun ResponseLoginDto.toUserInfo(): LoginInfo =
LoginInfo(
accessToken = accessToken,
refreshToken = refreshToken,
isNewUser = isNewUser,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.memento.data.mapper.toData.toData
import org.memento.data.mapper.toDomain.toUserInfo
import org.memento.data.util.handleBaseResponse
import org.memento.domain.entity.Login
import org.memento.domain.entity.UserInfo
import org.memento.domain.entity.LoginInfo
import org.memento.domain.repository.LoginRepository
import javax.inject.Inject

Expand All @@ -14,7 +14,7 @@ class LoginRepositoryImpl
constructor(
private val loginDataSource: LoginDataSource,
) : LoginRepository {
override suspend fun postLogin(login: Login): Result<UserInfo> {
override suspend fun postLogin(login: Login): Result<LoginInfo> {
return runCatching {
loginDataSource.postLogin(
requestLoginDto = login.toData(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.memento.data.repositoryimpl

import org.memento.data.datasource.UserInfoDataSource
import org.memento.data.mapper.toData.toData
import org.memento.domain.entity.UserInfo
import org.memento.domain.repository.UserInfoUpdateRepository
import javax.inject.Inject

class UserInfoUpdateRepositoryImpl
@Inject
constructor(
private val userInfoDataSource: UserInfoDataSource,
) : UserInfoUpdateRepository {
override suspend fun fetchUserInfo(userInfo: UserInfo): Result<Unit> {
return runCatching {
userInfoDataSource.fetchUserInfo(
requestUserInfo = userInfo.toData(),
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.memento.data.service

import org.memento.data.dto.BaseResponse
import org.memento.data.dto.request.RequestUserInfoUpdateDto
import retrofit2.http.Body
import retrofit2.http.PATCH

interface UserInfoUpdateService {
@PATCH("/api/v1/members/personal-info")
suspend fun fetchUserInfo(
@Body requestUserInfo: RequestUserInfoUpdateDto,
): BaseResponse<Unit>
}
6 changes: 6 additions & 0 deletions app/src/main/java/org/memento/di/DataSourceModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import org.memento.data.datasource.LoginDataSource
import org.memento.data.datasource.ReqresDataSource
import org.memento.data.datasource.ScheduleDataSource
import org.memento.data.datasource.TodoDataSource
import org.memento.data.datasource.UserInfoDataSource
import org.memento.data.datasourceimpl.AddPlanDataSourceImpl
import org.memento.data.datasourceimpl.LoginDataSourceImpl
import org.memento.data.datasourceimpl.ReqresDataSourceImpl
import org.memento.data.datasourceimpl.ScheduleDataSourceImpl
import org.memento.data.datasourceimpl.TodoDataSourceImpl
import org.memento.data.datasourceimpl.UserDataSourceImpl
import javax.inject.Singleton

@Module
Expand All @@ -31,6 +33,10 @@ internal abstract class DataSourceModule {
@Singleton
abstract fun bindsAddPlanDataSource(addScheduleDataSourceImpl: AddPlanDataSourceImpl): AddPlanDataSource

@Binds
@Singleton
abstract fun bindsUserDataSource(userDataSourceImpl: UserDataSourceImpl): UserInfoDataSource

@Binds
@Singleton
abstract fun bindsScheduleDataSource(scheduleDataSourceImpl: ScheduleDataSourceImpl): ScheduleDataSource
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/org/memento/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import org.memento.data.repositoryimpl.LoginRepositoryImpl
import org.memento.data.repositoryimpl.ReqresRepositoryImpl
import org.memento.data.repositoryimpl.ScheduleRepositoryImpl
import org.memento.data.repositoryimpl.TodoRepositoryImpl
import org.memento.data.repositoryimpl.UserInfoUpdateRepositoryImpl
import org.memento.domain.repository.AddPlanRepository
import org.memento.domain.repository.LoginRepository
import org.memento.domain.repository.ReqresRepository
import org.memento.domain.repository.ScheduleRepository
import org.memento.domain.repository.TodoRepository
import org.memento.domain.repository.UserInfoUpdateRepository
import javax.inject.Singleton

@Module
Expand All @@ -35,6 +37,10 @@ internal abstract class RepositoryModule {
@Singleton
abstract fun bindsScheduleRepository(scheduleRepositoryImpl: ScheduleRepositoryImpl): ScheduleRepository

@Binds
@Singleton
abstract fun bindsUserRepository(userInfoUpdateRepositoryImpl: UserInfoUpdateRepositoryImpl): UserInfoUpdateRepository

@Binds
@Singleton
abstract fun bindsTodoRepository(todoRepositoryImpl: TodoRepositoryImpl): TodoRepository
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/org/memento/di/ServiceModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.memento.data.service.LoginService
import org.memento.data.service.ReqresService
import org.memento.data.service.ScheduleService
import org.memento.data.service.TodoService
import org.memento.data.service.UserInfoUpdateService
import retrofit2.Retrofit
import javax.inject.Singleton

Expand All @@ -31,6 +32,10 @@ internal object ServiceModule {
@Singleton
fun provideScheduleService(retrofit: Retrofit): ScheduleService = retrofit.create(ScheduleService::class.java)

@Provides
@Singleton
fun provideUserInfoUpdateService(retrofit: Retrofit): UserInfoUpdateService = retrofit.create(UserInfoUpdateService::class.java)

@Provides
@Singleton
fun provideTodoService(retrofit: Retrofit): TodoService = retrofit.create(TodoService::class.java)
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/org/memento/domain/entity/Login.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ data class Login(
val idToken: String,
)

data class UserInfo(
data class LoginInfo(
val accessToken: String,
val refreshToken: String,
val isNewUser: Boolean,
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/java/org/memento/domain/entity/UserInfo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.memento.domain.entity

data class UserInfo(
val wakeUpTime: String,
val windDownTime: String,
val job: String,
val jobOtherDetail: String? = null,
val isStressedUnorganizedSchedule: Boolean,
val isForgetImportantThings: Boolean,
val isPreferReminder: Boolean,
val isImportantBreaks: Boolean,
)
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.memento.domain.repository

import org.memento.domain.entity.Login
import org.memento.domain.entity.UserInfo
import org.memento.domain.entity.LoginInfo

interface LoginRepository {
suspend fun postLogin(login: Login): Result<UserInfo>
suspend fun postLogin(login: Login): Result<LoginInfo>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.memento.domain.repository

import org.memento.domain.entity.UserInfo

interface UserInfoUpdateRepository {
suspend fun fetchUserInfo(
userInfo: UserInfo,
): Result<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import com.google.android.gms.common.api.ApiException
import org.memento.BuildConfig
import org.memento.R
import org.memento.core.util.UiState
import org.memento.domain.entity.UserInfo
import org.memento.domain.entity.LoginInfo
import org.memento.presentation.onboarding.component.SocialLoginButton
import org.memento.presentation.onboarding.viewmodel.LoginViewModel
import org.memento.presentation.util.noRippleClickable
Expand Down Expand Up @@ -69,7 +69,7 @@ fun LoginScreen(
when (uiState) {
is UiState.Loading -> {}
is UiState.Success -> {
val data = (uiState as UiState.Success<UserInfo>).data
val data = (uiState as UiState.Success<LoginInfo>).data
viewModel.saveToken(
accessToken = data.accessToken,
refreshToken = data.refreshToken,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,43 @@ 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.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.memento.R
import org.memento.presentation.component.MementoBottomSheet
import org.memento.presentation.component.MementoChipSelector
import org.memento.presentation.component.MementoWakeTimePicker
import org.memento.presentation.onboarding.component.OnboardingBottomButton
import org.memento.presentation.onboarding.component.OnboardingTopAppBar
import org.memento.presentation.onboarding.viewmodel.OnboardingViewModel
import org.memento.presentation.type.OnboardingTopType
import org.memento.presentation.type.SelectorType
import org.memento.presentation.type.SetTimeType
import org.memento.ui.theme.darkModeColors
import org.memento.ui.theme.defaultMementoTypography

enum class SETTIME {
WAKEUP,
WINDDOWN,
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun OnboardingScreen1(
viewModel: OnboardingViewModel = hiltViewModel(),
navigateToOnboardingScreen2: () -> Unit,
navigateToOnboardingScreen4: () -> Unit,
) {
val initialTimeText = stringResource(id = R.string.time_example)

val selectedTimeTextWakeUp by viewModel.wakeUpTime.collectAsStateWithLifecycle(initialTimeText)
val selectedTimeTextWindDown by viewModel.windDownTime.collectAsStateWithLifecycle(initialTimeText)

val sheetTimePickerState = rememberModalBottomSheetState()
var showTimePickerBottomSheet by remember { mutableStateOf(false) }

var selectedTimeTextWakeUp by remember { mutableStateOf(initialTimeText) }
var selectedTimeTextWindDown by remember { mutableStateOf(initialTimeText) }

var isClickedWakeUp by remember { mutableStateOf(false) }
var isClickedWindDown by remember { mutableStateOf(false) }

var isSelectedWakeUp by remember { mutableStateOf(false) }
var isSelectedWindDown by remember { mutableStateOf(false) }

var currentActiveSelector by remember { mutableStateOf<SETTIME?>(null) }
var currentActiveSelector by remember { mutableStateOf<SetTimeType?>(null) }

Column(
modifier =
Expand All @@ -66,7 +67,10 @@ fun OnboardingScreen1(
) {
OnboardingTopAppBar(
type = OnboardingTopType.PAGE1,
onSkipClick = navigateToOnboardingScreen4,
onSkipClick = {
viewModel.fetchUserInfoUpdate()
navigateToOnboardingScreen4()
},
)
Spacer(Modifier.height(40.dp))
Column {
Expand All @@ -89,10 +93,10 @@ fun OnboardingScreen1(
)
MementoChipSelector(
selectorType = SelectorType.TIMESELECTOR,
content = selectedTimeTextWakeUp,
content = selectedTimeTextWakeUp ?: initialTimeText,
isClicked = isClickedWakeUp,
onClickedChange = {
currentActiveSelector = SETTIME.WAKEUP
currentActiveSelector = SetTimeType.WAKEUP
showTimePickerBottomSheet = true
},
)
Expand All @@ -117,10 +121,10 @@ fun OnboardingScreen1(
)
MementoChipSelector(
selectorType = SelectorType.TIMESELECTOR,
content = selectedTimeTextWindDown,
content = selectedTimeTextWindDown ?: initialTimeText,
isClicked = isClickedWindDown,
onClickedChange = {
currentActiveSelector = SETTIME.WINDDOWN
currentActiveSelector = SetTimeType.WINDDOWN
showTimePickerBottomSheet = true
},
)
Expand All @@ -131,15 +135,15 @@ fun OnboardingScreen1(
MementoWakeTimePicker(
onTimeSelected = { selectedTime ->
when (currentActiveSelector) {
SETTIME.WAKEUP -> {
selectedTimeTextWakeUp = selectedTime
SetTimeType.WAKEUP -> {
viewModel.setWakeUpTime(selectedTime)
isClickedWakeUp = true
isClickedWindDown = false
isSelectedWakeUp = true
}

SETTIME.WINDDOWN -> {
selectedTimeTextWindDown = selectedTime
SetTimeType.WINDDOWN -> {
viewModel.setWindDownTime(selectedTime)
isClickedWindDown = true
isClickedWakeUp = false
}
Expand All @@ -155,7 +159,7 @@ fun OnboardingScreen1(
isClickedWakeUp = false
isClickedWindDown = false

if (currentActiveSelector == SETTIME.WINDDOWN) {
if (currentActiveSelector == SetTimeType.WINDDOWN) {
isSelectedWindDown = true
}
},
Expand All @@ -165,7 +169,12 @@ fun OnboardingScreen1(
OnboardingBottomButton(
content = R.string.onboarding_next,
isSelected = isSelectedWakeUp && isSelectedWindDown,
onSelected = { if (isSelectedWakeUp && isSelectedWindDown) navigateToOnboardingScreen2() },
onSelected = {
if (isSelectedWakeUp && isSelectedWindDown) {
viewModel.fetchUserInfoUpdate()
navigateToOnboardingScreen2()
}
},
)
}
}
Loading

0 comments on commit 061707f

Please sign in to comment.