Skip to content

Commit

Permalink
[chore] #61 중간고사 기말고사 선택 API 연동
Browse files Browse the repository at this point in the history
  • Loading branch information
beom84 committed Jan 23, 2025
1 parent 22a7c6e commit 37b10cb
Show file tree
Hide file tree
Showing 14 changed files with 247 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.android.bbangzip.data.datasource.remote

import org.android.bbangzip.data.dto.response.ResponseExamNameDto
import org.android.bbangzip.data.service.ExamService
import org.android.bbangzip.data.util.base.BaseResponse
import javax.inject.Inject

class ExamRemoteDataSource
@Inject
constructor(
private val examService: ExamService,
) {
suspend fun getSubjectDetail(
subjectId: Int,
examName: String,
):BaseResponse<ResponseExamNameDto?> = examService.getSubjectDetail(subjectId = subjectId, examName = examName)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.android.bbangzip.data.dto.response


import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.android.bbangzip.domain.model.SubjectDetailInfoEntity
import org.android.bbangzip.domain.model.ToDoCardEntity

@Serializable
data class ResponseExamNameDto(
@SerialName("examDate")
val examDate: String,
@SerialName("examDday")
val examDday: Int,
@SerialName("motivationMessage")
val motivationMessage: String,
@SerialName("studyList")
val studyList: List<StudyInfo>
){
fun toSubjectDetailInfoEntity() = SubjectDetailInfoEntity(
examDate = examDate,
examDday = examDday,
motivationMessage = motivationMessage,
todoList = studyList.map { it.toToDoCardEntity() }
)
}

@Serializable
data class StudyInfo(
@SerialName("deadline")
val deadline: String,
@SerialName("finishPage")
val finishPage: Int,
@SerialName("isFinished")
val isFinished: Boolean,
@SerialName("pieceId")
val pieceId: Int,
@SerialName("remainingDays")
val remainingDays: Int,
@SerialName("startPage")
val startPage: Int,
@SerialName("studyContents")
val studyContents: String
){
fun toToDoCardEntity() = ToDoCardEntity(
deadline = deadline,
finishPage = finishPage,
pieceId = pieceId,
remainingDays = remainingDays,
startPage = startPage,
studyContents = studyContents,
isFinished = isFinished
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.android.bbangzip.data.repositoryImpl.remote

import org.android.bbangzip.data.datasource.remote.ExamRemoteDataSource
import org.android.bbangzip.domain.model.SubjectDetailInfoEntity
import org.android.bbangzip.domain.repository.remote.ExamRepository
import javax.inject.Inject

class ExamRepositoryImpl
@Inject
constructor(
private val examRemoteDataSource: ExamRemoteDataSource,
) : ExamRepository {
override suspend fun getSubjectDetail(
subjectId: Int,
examName: String,
): Result<SubjectDetailInfoEntity> =
runCatching {
val response = examRemoteDataSource.getSubjectDetail(subjectId = subjectId, examName = examName)

val responseData = response.data ?: throw IllegalStateException(response.message ?: "Null Error")

responseData.toSubjectDetailInfoEntity()
}
}
14 changes: 14 additions & 0 deletions app/src/main/java/org/android/bbangzip/data/service/ExamService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.android.bbangzip.data.service

import org.android.bbangzip.data.dto.response.ResponseExamNameDto
import org.android.bbangzip.data.util.base.BaseResponse
import retrofit2.http.GET
import retrofit2.http.Path

interface ExamService {
@GET("/api/v1/exams/{subjectId}/{examName}")
suspend fun getSubjectDetail(
@Path("subjectId") subjectId: Int,
@Path("examName") examName: String,
): BaseResponse<ResponseExamNameDto?>
}
6 changes: 6 additions & 0 deletions app/src/main/java/org/android/bbangzip/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.android.bbangzip.data.repositoryImpl.local.UserLocalRepositoryImpl
import org.android.bbangzip.data.repositoryImpl.remote.DummyRepositoryImpl
import org.android.bbangzip.data.repositoryImpl.remote.ExamRepositoryImpl
import org.android.bbangzip.data.repositoryImpl.remote.MyPageRepositoryImpl
import org.android.bbangzip.data.repositoryImpl.remote.PieceRepositoryImpl
import org.android.bbangzip.data.repositoryImpl.remote.UserRepositoryImpl
import org.android.bbangzip.domain.repository.local.UserLocalRepository
import org.android.bbangzip.domain.repository.remote.DummyRepository
import org.android.bbangzip.domain.repository.remote.ExamRepository
import org.android.bbangzip.domain.repository.remote.MyPageRepository
import org.android.bbangzip.domain.repository.remote.PieceRepository
import org.android.bbangzip.domain.repository.remote.UserRepository
Expand Down Expand Up @@ -38,4 +40,8 @@ abstract class RepositoryModule {
@Binds
@Singleton
abstract fun bindsMyPageRepository(repositoryImpl: MyPageRepositoryImpl): MyPageRepository

@Binds
@Singleton
abstract fun bindsExamRepository(repositoryImpl: ExamRepositoryImpl): ExamRepository
}
8 changes: 8 additions & 0 deletions app/src/main/java/org/android/bbangzip/di/ServiceModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.android.bbangzip.data.service.DummyService
import org.android.bbangzip.data.service.ExamService
import org.android.bbangzip.data.service.MyPageService
import org.android.bbangzip.data.service.PieceService
import org.android.bbangzip.data.service.UserService
Expand Down Expand Up @@ -41,4 +42,11 @@ object ServiceModule {
@BbangZip retrofit: Retrofit,
): UserService =
retrofit.create(UserService::class.java)

@Provides
@Singleton
fun provideExamService(
@BbangZip retrofit: Retrofit,
): ExamService =
retrofit.create(ExamService::class.java)
}
7 changes: 7 additions & 0 deletions app/src/main/java/org/android/bbangzip/di/UseCaseModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.android.bbangzip.domain.repository.remote.DummyRepository
import org.android.bbangzip.domain.repository.remote.ExamRepository
import org.android.bbangzip.domain.repository.remote.MyPageRepository
import org.android.bbangzip.domain.repository.remote.PieceRepository
import org.android.bbangzip.domain.repository.remote.UserRepository
Expand All @@ -15,6 +16,7 @@ import org.android.bbangzip.domain.usecase.FetchDummyUseCase
import org.android.bbangzip.domain.usecase.GetAddTodoListUseCase
import org.android.bbangzip.domain.usecase.GetBadgeCategoryListUseCase
import org.android.bbangzip.domain.usecase.GetBadgeDetailUseCase
import org.android.bbangzip.domain.usecase.GetSubjectDetailUseCase
import org.android.bbangzip.domain.usecase.GetToInfoUseCase
import org.android.bbangzip.domain.usecase.PostAddTodoItemListUseCase
import org.android.bbangzip.domain.usecase.PostCompleteCardIdUseCase
Expand Down Expand Up @@ -90,4 +92,9 @@ class UseCaseModule {
@Singleton
fun providesFetchBbangZipUseCase(myPageRepository: MyPageRepository): FetchBbangZipUseCase =
FetchBbangZipUseCase(myPageRepository = myPageRepository)

@Provides
@Singleton
fun providesGetSubjectDetailUseCase(examRepository: ExamRepository): GetSubjectDetailUseCase =
GetSubjectDetailUseCase(examRepository = examRepository)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.android.bbangzip.domain.model

data class SubjectDetailInfoEntity(
val examDate: String,
val examDday: Int,
val motivationMessage: String,
val todoList: List<ToDoCardEntity>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.android.bbangzip.domain.repository.remote

import org.android.bbangzip.domain.model.SubjectDetailInfoEntity

interface ExamRepository {
suspend fun getSubjectDetail(
subjectId: Int,
examName: String,
) : Result<SubjectDetailInfoEntity>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.android.bbangzip.domain.usecase

import org.android.bbangzip.domain.model.BadgeDetailEntity
import org.android.bbangzip.domain.model.SubjectDetailInfoEntity
import org.android.bbangzip.domain.repository.remote.ExamRepository
import org.android.bbangzip.domain.repository.remote.MyPageRepository

class GetSubjectDetailUseCase(
private val examRepository: ExamRepository,
) {
suspend operator fun invoke(subjectId: Int, examName: String): Result<SubjectDetailInfoEntity> =
examRepository.getSubjectDetail(subjectId = subjectId, examName = examName)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.android.bbangzip.presentation.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.android.bbangzip.presentation.model.card.ToDoCardModel

@Parcelize
data class SubjectDetailInfo(
val examDate: String,
val examDday: Int,
val motivationMessage: String,
val todoList: List<ToDoCardModel>
): Parcelable
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import org.android.bbangzip.presentation.model.BottomNavigationRoute
import org.android.bbangzip.presentation.model.Route
import org.android.bbangzip.presentation.type.BottomNavigationType
import org.android.bbangzip.presentation.ui.friend.navigation.navigateFriend
import org.android.bbangzip.presentation.ui.login.LoginRoute
import org.android.bbangzip.presentation.ui.login.navigateLogin
import org.android.bbangzip.presentation.ui.my.bbangzipdetail.navigation.navigateBbangZipDetail
import org.android.bbangzip.presentation.ui.my.mybadgecategory.navigation.navigateToMyBadgeCategory
import org.android.bbangzip.presentation.ui.my.navigation.navigateMy
import org.android.bbangzip.presentation.ui.onboarding.navigation.navigateOnboarding
import org.android.bbangzip.presentation.ui.onboarding.navigation.navigateOnboardingEnd
import org.android.bbangzip.presentation.ui.onboarding.navigation.navigateOnboardingStart
import org.android.bbangzip.presentation.ui.subject.navigateSubject
import org.android.bbangzip.presentation.ui.subject.subjectdetail.SubjectDetailRoute
import org.android.bbangzip.presentation.ui.todo.navigation.navigateTodo
import org.android.bbangzip.presentation.ui.todo.pendingtodoadd.navigation.navigateTodoAddPending
import org.android.bbangzip.presentation.ui.todo.todoadd.navigation.navigateTodoAdd
Expand All @@ -31,7 +32,7 @@ class MainNavigator(
private val currentDestination: NavDestination?
@Composable get() = navHostController.currentBackStackEntryAsState().value?.destination

val startDestination = LoginRoute
val startDestination = SubjectDetailRoute

val currentBottomNavigationBarItem: BottomNavigationType?
@Composable get() =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.android.bbangzip.presentation.ui.subject.subjectdetail
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.android.bbangzip.presentation.component.card.BbangZipCardState
import org.android.bbangzip.presentation.model.SubjectDetailInfo
import org.android.bbangzip.presentation.model.card.ToDoCardModel
import org.android.bbangzip.presentation.type.PieceViewType
import org.android.bbangzip.presentation.util.base.BaseContract
Expand All @@ -16,7 +17,11 @@ class SubjectDetailContract {
val pieceViewType: PieceViewType = PieceViewType.DEFAULT,
val selectedItemSet: Set<Int> = setOf(),
val revertCompleteBottomSheetState: Boolean = false,
val examDate: String = "",
val examDday : Int = 0,
val motivationMessage : String = "",
val selectedItemId: Int = -1,
val subjectId : Int = 0,
val todoList: List<ToDoCardModel> =
listOf(
ToDoCardModel(
Expand Down Expand Up @@ -165,6 +170,8 @@ class SubjectDetailContract {
}

sealed interface SubjectDetailReduce : BaseContract.Reduce {
data class UpdateSubjectDetail(val subjectDetailInfo: SubjectDetailInfo) : SubjectDetailReduce

data object UpdateToDeleteMode : SubjectDetailReduce

data object UpdateToDefaultMode : SubjectDetailReduce
Expand All @@ -179,6 +186,8 @@ class SubjectDetailContract {

data class DeleteSelectedItemSet(val pieceId: Int) : SubjectDetailReduce

data class UpdateSubjectId (val subjectId: Int) : SubjectDetailReduce

data object UpdateRevertCompleteBottomSheetState : SubjectDetailReduce

data class UpdateSelectedId(val pieceId: Int) : SubjectDetailReduce
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import org.android.bbangzip.data.dto.request.RequestMarkDoneDto
import org.android.bbangzip.domain.usecase.GetSubjectDetailUseCase
import org.android.bbangzip.domain.usecase.PostCompleteCardIdUseCase
import org.android.bbangzip.domain.usecase.PostUnCompleteCardIdUseCase
import org.android.bbangzip.presentation.component.card.BbangZipCardState
import org.android.bbangzip.presentation.model.SubjectDetailInfo
import org.android.bbangzip.presentation.model.card.ToDoCardModel
import org.android.bbangzip.presentation.type.PieceViewType
import org.android.bbangzip.presentation.util.base.BaseViewModel
import timber.log.Timber
Expand All @@ -20,6 +23,7 @@ class SubjectDetailViewModel
constructor(
private val postCompleteCardIdUseCase: PostCompleteCardIdUseCase,
private val postUnCompleteCardIdUseCase: PostUnCompleteCardIdUseCase,
private val getSubjectDetailUseCase: GetSubjectDetailUseCase,
savedStateHandle: SavedStateHandle,
) : BaseViewModel<SubjectDetailContract.SubjectDetailEvent, SubjectDetailContract.SubjectDetailState, SubjectDetailContract.SubjectDetailReduce, SubjectDetailContract.SubjectDetailSideEffect>(
savedStateHandle = savedStateHandle,
Expand All @@ -34,7 +38,7 @@ constructor(

override fun handleEvent(event: SubjectDetailContract.SubjectDetailEvent) {
when (event) {
is SubjectDetailContract.SubjectDetailEvent.Initialize -> {}
is SubjectDetailContract.SubjectDetailEvent.Initialize -> launch { initData() }

is SubjectDetailContract.SubjectDetailEvent.OnTrashIconClicked -> {
updateState(SubjectDetailContract.SubjectDetailReduce.UpdateToDeleteMode)
Expand Down Expand Up @@ -189,10 +193,66 @@ constructor(
)
}

is SubjectDetailContract.SubjectDetailReduce.UpdateSubjectDetail -> {
state.copy(
examDate = reduce.subjectDetailInfo.examDate,
examDday = reduce.subjectDetailInfo.examDday,
motivationMessage = reduce.subjectDetailInfo.motivationMessage,
todoList = reduce.subjectDetailInfo.todoList,
)
}

is SubjectDetailContract.SubjectDetailReduce.UpdateSubjectId -> {
state.copy(
subjectId = reduce.subjectId,
)
}

else -> state
}
}

private suspend fun initData(){
getSubjectDetail(
subjectId = 4,
examName = "mid",
)
}

private suspend fun getSubjectDetail(
subjectId: Int,
examName: String,
) {
getSubjectDetailUseCase(
subjectId = subjectId,
examName = examName,
).onSuccess { subjectDetailInfoEntity ->
updateState(SubjectDetailContract.SubjectDetailReduce.UpdateSubjectDetail(
subjectDetailInfo = SubjectDetailInfo(
examDate = subjectDetailInfoEntity.examDate,
examDday = subjectDetailInfoEntity.examDday,
motivationMessage = subjectDetailInfoEntity.motivationMessage,
todoList = subjectDetailInfoEntity.todoList.map { data ->
ToDoCardModel(
pieceId = data.pieceId,
subjectName = data.subjectName,
examName = data.examName,
studyContents = data.studyContents,
startPage = data.startPage,
finishPage = data.finishPage,
deadline = data.deadline,
remainingDays = data.remainingDays,
cardState = if (data.isFinished) BbangZipCardState.COMPLETE else BbangZipCardState.DEFAULT,
)
}

)
))
}.onFailure { error ->
Timber.tag("getSubjectDetail").e(error)
}
}

private suspend fun postUnCompleteCardId(
pieceId: Int,
) {
Expand Down

0 comments on commit 37b10cb

Please sign in to comment.