Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@ import retrofit2.http.*
*/
interface DailyRecordApiService {

// 전체 기록 목록 조회
@GET("daily-question")
suspend fun getDailyQuestion(): DailyQuestionResponse

@GET("mind-records")
suspend fun getMindRecords(): MindRecordListResponse
suspend fun getMindRecords(
@Query("type") type: String,
@Query("view") view: String = "LIST",
@Query("year") year: Int? = null,
@Query("month") month: Int? = null
): MindRecordListResponse

// 기록 작성
@POST("mind-records")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.kuit.afternote.feature.dailyrecord.data.dto

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable

import kotlinx.serialization.json.JsonNames

/**
* 마음의 기록 API DTOs. (스웨거 기준)
Expand All @@ -27,27 +28,31 @@ data class MindRecordListResponse(
*/
@Serializable
data class MindRecordListData(
/** 기록 요약 리스트 */
/** 기록 요약 리스트 (각 항목에 content 포함) */
val records: List<MindRecordSummary>,
/** 표시된 날짜들 (달력 하이라이트용) */
val markedDates: List<String>? = emptyList()
)

/**
* 기록 요약 정보
* DAILY_QUESTION 타입은 API에서 question 필드로 질문 내용을 반환할 수 있음.
*/
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class MindRecordSummary(
/** 기록 고유 ID */
val recordId: Long,
/** 기록 타입 (예: DIARY, LETTER 등) */
val type: String,
/** 기록 제목 */
val title: String,
/** 기록 제목 (API: title 또는 question) */
@JsonNames("question", "title") val title: String? = null,
/** 기록 날짜 (yyyy-MM-dd) */
val date: String,
/** 임시 저장 여부 */
val isDraft: Boolean
val isDraft: Boolean,
/** 기록 내용 (API: content 또는 answer). DAILY_QUESTION은 answer로 반환될 수 있음. */
@JsonNames("answer", "content") val content: String? = null
)

/**
Expand Down Expand Up @@ -79,6 +84,17 @@ data class MindRecordDetail(
val category: String?
)

/**
* 데일리 질문 조회 응답 (GET /daily-question)
* 오늘 날짜 기준으로 서버가 1개의 질문을 반환합니다.
* API 스펙: { questionId, content }
*/
@Serializable
data class DailyQuestionResponse(
val questionId: Long,
val content: String
)

/**
* 기록 작성 요청 DTO (POST /mind-records)
*/
Expand Down Expand Up @@ -118,12 +134,19 @@ data class PostMindRecordData(
@Serializable
data class CreateMindRecordRequest(
val type: String,
val title: String?, // nullable 허용
val content: String?, // nullable 허용
val date: String?, // nullable 허용
val title: String?,
val content: String?,
val date: String?,
val isDraft: Boolean,
val questionId: Long? = null,
val category: String? = null
val category: String? = null,
val imageList: List<MindRecordImageItem>? = emptyList() // 추가
)

@Serializable
data class MindRecordImageItem(
val mediaType: String,
val imageUrl: String
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,17 @@ import com.kuit.afternote.feature.dailyrecord.data.dto.MindRecordDetailResponse
import com.kuit.afternote.feature.dailyrecord.data.dto.MindRecordListResponse
import com.kuit.afternote.feature.dailyrecord.data.dto.PostMindRecordRequest
import com.kuit.afternote.feature.dailyrecord.data.dto.PostMindRecordResponse
import com.kuit.afternote.feature.dailyrecord.domain.model.DailyQuestionData

interface MindRecordRepository {
suspend fun getMindRecords(): MindRecordListResponse
suspend fun getDailyQuestion(): DailyQuestionData?

suspend fun getMindRecords(
type: String,
view: String = "LIST",
year: Int? = null,
month: Int? = null
): MindRecordListResponse

suspend fun createMindRecord(request: CreateMindRecordRequest): PostMindRecordResponse

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,38 @@ import com.kuit.afternote.feature.dailyrecord.data.dto.MindRecordDetailResponse
import com.kuit.afternote.feature.dailyrecord.data.dto.MindRecordListResponse
import com.kuit.afternote.feature.dailyrecord.data.dto.PostMindRecordRequest
import com.kuit.afternote.feature.dailyrecord.data.dto.PostMindRecordResponse
import com.kuit.afternote.feature.dailyrecord.domain.model.DailyQuestionData
import retrofit2.HttpException
import javax.inject.Inject

class MindRecordRepositoryImpl @Inject constructor(
private val apiService: DailyRecordApiService
) : MindRecordRepository{
override suspend fun getMindRecords(): MindRecordListResponse {
return apiService.getMindRecords()
) : MindRecordRepository {
override suspend fun getDailyQuestion(): DailyQuestionData? = try {
val response = apiService.getDailyQuestion()
DailyQuestionData(questionId = response.questionId, content = response.content)
} catch (e: Exception) {
null
}

override suspend fun getMindRecords(
type: String,
view: String,
year: Int?,
month: Int?
): MindRecordListResponse {
return apiService.getMindRecords(type = type, view = view, year = year, month = month)
}

override suspend fun createMindRecord(request: CreateMindRecordRequest): PostMindRecordResponse {
return apiService.createMindRecord(request)
}

override suspend fun deleteMindRecord(recordId: Long) {
apiService.deleteMindRecord(recordId)
val response = apiService.deleteMindRecord(recordId)
if (!response.isSuccessful) {
throw HttpException(response)
}
}
override suspend fun getMindRecord(recordId: Long): MindRecordDetailResponse {
val response = apiService.getMindRecord(recordId)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.kuit.afternote.feature.dailyrecord.domain.model

/**
* 오늘의 데일리 질문 정보.
* GET /daily-question API 응답을 도메인 모델로 변환한 결과.
*
* @param questionId 데일리 질문 ID (POST /mind-records 시 필수)
* @param content 질문 내용 (UI 표시용)
*/
data class DailyQuestionData(
val questionId: Long,
val content: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.kuit.afternote.feature.dailyrecord.domain.model

import com.kuit.afternote.feature.dailyrecord.data.dto.MindRecordSummary

/**
* 마음의 기록 목록 조회 결과 (records + markedDates)
*/
data class MindRecordsResult(
val records: List<MindRecordSummary>,
val markedDates: List<String> = emptyList()
)
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,15 @@ class CreateMindRecordUseCase @Inject constructor(
category: String? = null
): Result<PostMindRecordResponse> {
return try {
val request = CreateMindRecordRequest(type, title, content, date, isDraft, questionId, category)
val request = CreateMindRecordRequest(
type = type,
title = title,
content = content ?: "",
date = date,
isDraft = isDraft,
questionId = questionId,
category = category
)
val response = repository.createMindRecord(request)
Result.success(response)
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.kuit.afternote.feature.dailyrecord.domain.usecase

import com.kuit.afternote.feature.dailyrecord.data.repository.MindRecordRepository
import com.kuit.afternote.feature.dailyrecord.domain.model.DailyQuestionData
import javax.inject.Inject

/**
* 오늘의 데일리 질문을 조회합니다.
* DAILY_QUESTION 타입 기록 작성 시 questionId가 필수이므로 등록 전에 호출합니다.
* content는 UI에 질문 텍스트를 표시할 때 사용합니다.
*
* @return 오늘의 질문 (questionId, content), 실패 시 null
*/
class GetDailyQuestionUseCase @Inject constructor(
private val repository: MindRecordRepository
) {
suspend operator fun invoke(): DailyQuestionData? = repository.getDailyQuestion()
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
package com.kuit.afternote.feature.dailyrecord.domain.usecase

import com.kuit.afternote.feature.dailyrecord.data.dto.MindRecordSummary
import com.kuit.afternote.feature.dailyrecord.data.repository.MindRecordRepositoryImpl
import com.kuit.afternote.feature.dailyrecord.domain.model.MindRecordsResult
import javax.inject.Inject

class GetMindRecordsUseCase @Inject constructor(
private val repository: MindRecordRepositoryImpl
) {
suspend operator fun invoke(): List<MindRecordSummary> {
val response = repository.getMindRecords()
return response.data?.records ?: emptyList()
suspend operator fun invoke(
type: String,
view: String,
year: Int?,
month: Int?
): MindRecordsResult {
val response = repository.getMindRecords(type, view, year, month)
val data = response.data
return MindRecordsResult(
records = data?.records ?: emptyList(),
markedDates = data?.markedDates ?: emptyList()
)
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
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.draw.clip
Expand All @@ -43,13 +47,24 @@ import java.util.Locale
@Composable
fun RecordCalendarSort(
modifier: Modifier = Modifier,
today: LocalDate
today: LocalDate,
markedDates: Set<String> = emptySet()
) {
val year = today.year
val month = today.monthValue
val formatter = DateTimeFormatter.ofPattern("yyyy년 mm월", Locale.KOREA)
val markedDates = listOf(1, 6, 8, 11, 13, 15, 16, 17, 25)
var selectedDate = today.dayOfMonth
val markedDaysInMonth = markedDates.mapNotNull { dateStr ->
runCatching {
val parts = dateStr.split("-")
if (parts.size == 3 &&
parts[0].toIntOrNull() == year &&
parts[1].toIntOrNull() == month
) {
parts[2].toIntOrNull()
} else null
}.getOrNull()
}.filterNotNull().toSet()
var selectedDate by remember { mutableStateOf(today.dayOfMonth) }

Box(
modifier = Modifier
Expand Down Expand Up @@ -125,10 +140,10 @@ fun RecordCalendarSort(
day == selectedDate -> Color(0xFF328BFF)
else -> Color.Transparent
}
).then(
if (day in markedDates) {
) .then(
if (day in markedDaysInMonth) {
Modifier.border(
width = 1.dp,
width = 2.dp,
color = Color(0xFF328BFF),
shape = CircleShape
)
Expand Down
Loading
Loading