-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
[FEAT/#91] ์บ๋ฆฐ๋๋ทฐ / ์คํฌ๋ฉ ๋ชฉ๋ก ์๋ฒํต์
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.terning.point.di | ||
|
||
import android.content.Context | ||
import android.content.SharedPreferences | ||
import com.terning.data.local.TerningDataStore | ||
import com.terning.data.local.TerningDataStoreImpl | ||
import dagger.Module | ||
import dagger.Provides | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.android.qualifiers.ApplicationContext | ||
import dagger.hilt.components.SingletonComponent | ||
import javax.inject.Singleton | ||
|
||
@Module | ||
@InstallIn(SingletonComponent::class) | ||
object DataStoreModule { | ||
|
||
@Provides | ||
@Singleton | ||
fun provideSharedPreferences(@ApplicationContext context: Context): SharedPreferences = | ||
context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE) | ||
|
||
@Provides | ||
@Singleton | ||
fun provideTerningDataStore(dataStoreImpl: TerningDataStoreImpl): TerningDataStore = | ||
dataStoreImpl | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package com.terning.core.extension | ||
|
||
fun<T> List<T>?.isListNotEmpty():Boolean = this.orEmpty().isNotEmpty() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.terning.data.datasource | ||
|
||
import com.terning.data.dto.BaseResponse | ||
import com.terning.data.dto.request.SignInRequestDto | ||
import com.terning.data.dto.response.SignInResponseDto | ||
|
||
interface AuthDataSource { | ||
suspend fun postSignIn( | ||
authorization: String, | ||
platform: SignInRequestDto | ||
): BaseResponse<SignInResponseDto> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.terning.data.datasource | ||
|
||
import com.terning.data.dto.BaseResponse | ||
import com.terning.data.dto.request.CalendarDayListRequestDto | ||
import com.terning.data.dto.request.CalendarMonthListRequestDto | ||
import com.terning.data.dto.request.CalendarMonthRequestDto | ||
import com.terning.data.dto.response.CalendarDayListResponseDto | ||
import com.terning.data.dto.response.CalendarMonthListResponseDto | ||
import com.terning.data.dto.response.CalendarMonthResponseDto | ||
|
||
interface CalendarDataSource { | ||
suspend fun getCalendarMonth(request: CalendarMonthRequestDto): BaseResponse<List<CalendarMonthResponseDto>> | ||
suspend fun getCalendarMonthList(request: CalendarMonthListRequestDto): BaseResponse<List<CalendarMonthListResponseDto>> | ||
suspend fun getCalendarDayList(request: CalendarDayListRequestDto): BaseResponse<List<CalendarDayListResponseDto>> | ||
} |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.terning.data.datasource | ||
|
||
import com.terning.data.dto.BaseResponse | ||
import com.terning.data.dto.response.SearchViewsResponseDto | ||
|
||
interface SearchDataSource { | ||
suspend fun getSearchViews(): BaseResponse<SearchViewsResponseDto> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.terning.data.datasourceimpl | ||
|
||
import com.terning.data.datasource.AuthDataSource | ||
import com.terning.data.dto.BaseResponse | ||
import com.terning.data.dto.request.SignInRequestDto | ||
import com.terning.data.dto.response.SignInResponseDto | ||
import com.terning.data.service.AuthService | ||
import javax.inject.Inject | ||
|
||
class AuthDataSourceImpl @Inject constructor( | ||
private val authService: AuthService | ||
) : AuthDataSource { | ||
override suspend fun postSignIn( | ||
authorization: String, | ||
platform: SignInRequestDto | ||
): BaseResponse<SignInResponseDto> = authService.postSignIn(authorization, platform) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.terning.data.datasourceimpl | ||
|
||
import com.terning.data.datasource.CalendarDataSource | ||
import com.terning.data.dto.BaseResponse | ||
import com.terning.data.dto.request.CalendarDayListRequestDto | ||
import com.terning.data.dto.request.CalendarMonthListRequestDto | ||
import com.terning.data.dto.request.CalendarMonthRequestDto | ||
import com.terning.data.dto.response.CalendarDayListResponseDto | ||
import com.terning.data.dto.response.CalendarMonthListResponseDto | ||
import com.terning.data.dto.response.CalendarMonthResponseDto | ||
import com.terning.data.service.CalendarService | ||
import javax.inject.Inject | ||
|
||
class CalendarDataSourceImpl @Inject constructor( | ||
private val calendarService: CalendarService | ||
) : CalendarDataSource { | ||
override suspend fun getCalendarMonth(request: CalendarMonthRequestDto): BaseResponse<List<CalendarMonthResponseDto>> = | ||
CalendarList.getCalendarScrapMonth(request) | ||
|
||
override suspend fun getCalendarMonthList(request: CalendarMonthListRequestDto): BaseResponse<List<CalendarMonthListResponseDto>> = | ||
CalendarList.getCalendarScrapMonthList(request) | ||
|
||
override suspend fun getCalendarDayList(request: CalendarDayListRequestDto): BaseResponse<List<CalendarDayListResponseDto>> = | ||
CalendarList.getCalendarScrapDayList(request) | ||
} |
Large diffs are not rendered by default.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.terning.data.datasourceimpl | ||
|
||
import com.terning.data.datasource.SearchDataSource | ||
import com.terning.data.dto.BaseResponse | ||
import com.terning.data.dto.response.SearchViewsResponseDto | ||
import com.terning.data.service.SearchService | ||
import javax.inject.Inject | ||
|
||
class SearchDataSourceImpl @Inject constructor( | ||
private val searchService: SearchService, | ||
) : SearchDataSource { | ||
override suspend fun getSearchViews(): BaseResponse<SearchViewsResponseDto> = | ||
searchService.getSearchViewsList() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.terning.data.dto.request | ||
|
||
data class CalendarDayListRequestDto( | ||
val date: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.terning.data.dto.request | ||
|
||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class CalendarMonthListRequestDto( | ||
@SerialName("deadline") | ||
val year: Int, | ||
@SerialName("scraps") | ||
val month: Int | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.terning.data.dto.request | ||
|
||
import com.terning.domain.entity.request.SignInRequestModel | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class SignInRequestDto( | ||
@SerialName("authType") | ||
val authType: String | ||
) | ||
|
||
fun SignInRequestModel.toSignInRequestDto(): SignInRequestDto = | ||
SignInRequestDto(authType = authType) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.terning.data.dto.response | ||
|
||
import com.terning.domain.entity.response.CalendarScrapDetailModel | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class CalendarDayListResponseDto( | ||
@SerialName("scrapId") | ||
val scrapId: Long, | ||
@SerialName("internshipAnnouncementId") | ||
val internshipAnnouncementId: Long, | ||
@SerialName("title") | ||
val title: String, | ||
@SerialName("dDay") | ||
val dDay: String, | ||
@SerialName("workingPeriod") | ||
val workingPeriod: String, | ||
@SerialName("color") | ||
val color: String, | ||
@SerialName("companyImage") | ||
val companyImage: String, | ||
@SerialName("startYear") | ||
val startYear: Int, | ||
@SerialName("startMonth") | ||
val startMonth: Int | ||
){ | ||
fun toScrapDetailModelList(): CalendarScrapDetailModel = | ||
CalendarScrapDetailModel( | ||
scrapId = scrapId, | ||
internshipAnnouncementId = internshipAnnouncementId, | ||
title = title, | ||
dDay = dDay, | ||
workingPeriod = workingPeriod, | ||
color = color, | ||
companyImage = companyImage, | ||
startYear = startYear, | ||
startMonth = startMonth, | ||
deadLine = "" | ||
) | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package com.terning.data.dto.response | ||
|
||
import com.terning.domain.entity.response.CalendarScrapDetailModel | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class CalendarMonthListResponseDto( | ||
@SerialName("deadline") | ||
val deadline: String, | ||
@SerialName("scraps") | ||
val scraps: List<Scrap> | ||
) { | ||
@Serializable | ||
data class Scrap( | ||
@SerialName("scrapId") | ||
val scrapId: Long, | ||
@SerialName("internshipAnnouncementId") | ||
val internshipAnnouncementId: Long, | ||
@SerialName("title") | ||
val title: String, | ||
@SerialName("dDay") | ||
val dDay: String, | ||
@SerialName("workingPeriod") | ||
val workingPeriod: String, | ||
@SerialName("color") | ||
val color: String, | ||
@SerialName("companyImage") | ||
val companyImage: String, | ||
@SerialName("startYear") | ||
val startYear: Int, | ||
@SerialName("startMonth") | ||
val startMonth: Int | ||
) | ||
|
||
fun toScrapDetailModelList(): List<CalendarScrapDetailModel> = scraps.map { scrap -> | ||
CalendarScrapDetailModel( | ||
scrapId = scrap.scrapId, | ||
internshipAnnouncementId = scrap.internshipAnnouncementId, | ||
title = scrap.title, | ||
dDay = scrap.dDay, | ||
workingPeriod = scrap.workingPeriod, | ||
color = scrap.color, | ||
companyImage = scrap.companyImage, | ||
startYear = scrap.startYear, | ||
startMonth = scrap.startMonth, | ||
deadLine = deadline | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.terning.data.dto.response | ||
|
||
import com.terning.domain.entity.response.CalendarScrapModel | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class CalendarMonthResponseDto( | ||
@SerialName("deadline") | ||
val deadline: String, | ||
@SerialName("scraps") | ||
val scraps: List<Scrap> | ||
) { | ||
@Serializable | ||
data class Scrap( | ||
@SerialName("scrapId") | ||
val scrapId: Long, | ||
@SerialName("title") | ||
val title: String, | ||
@SerialName("color") | ||
val color: String | ||
) | ||
|
||
fun toScrapModelList(): List<CalendarScrapModel> = scraps.map { scrap -> | ||
CalendarScrapModel( | ||
scrapId = scrap.scrapId, | ||
title = scrap.title, | ||
color = scrap.color, | ||
deadLine = deadline, | ||
isScrapped = true | ||
) | ||
} | ||
} |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.terning.data.dto.response | ||
|
||
import com.terning.domain.entity.response.InternshipAnnouncement | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class SearchViewsResponseDto( | ||
@SerialName("internshipAnnouncementId") | ||
val internshipAnnouncementId: Long, | ||
@SerialName("companyImage") | ||
val companyImage: String, | ||
@SerialName("title") | ||
val title: String, | ||
) { | ||
|
||
|
||
fun toSearchViewsEntity(): List<InternshipAnnouncement> { | ||
return listOf( | ||
InternshipAnnouncement( | ||
announcementId = internshipAnnouncementId, | ||
companyImage = companyImage, | ||
title = title, | ||
) | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.terning.data.dto.response | ||
|
||
import com.terning.domain.entity.response.SignInResponseModel | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class SignInResponseDto( | ||
@SerialName("accessToken") | ||
val accessToken: String, | ||
@SerialName("refreshToken") | ||
val refreshToken: String, | ||
@SerialName("userId") | ||
val userId: Long, | ||
@SerialName("authType") | ||
val authType: String, | ||
) { | ||
fun toSignInModel() = SignInResponseModel( | ||
accessToken = accessToken, | ||
refreshToken = refreshToken, | ||
userId = userId, | ||
authType = authType | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.terning.data.local | ||
|
||
interface TerningDataStore { | ||
var accessToken: String | ||
var refreshToken: String | ||
var userId: Long | ||
fun clearInfo() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.terning.data.local | ||
|
||
import android.content.SharedPreferences | ||
import androidx.core.content.edit | ||
import javax.inject.Inject | ||
|
||
class TerningDataStoreImpl @Inject constructor( | ||
private val dataStore: SharedPreferences, | ||
) : TerningDataStore { | ||
override var accessToken: String | ||
get() = dataStore.getString(ACCESS_TOKEN, "") ?: "" | ||
set(value) = dataStore.edit { putString(ACCESS_TOKEN, value) } | ||
|
||
override var refreshToken: String | ||
get() = dataStore.getString(REFRESH_TOKEN, "") ?: "" | ||
set(value) = dataStore.edit { putString(REFRESH_TOKEN, value) } | ||
|
||
override var userId: Long | ||
get() = dataStore.getLong(USER_ID, 0L) | ||
set(value) = dataStore.edit { putLong(USER_ID, value) } | ||
|
||
override fun clearInfo() { | ||
dataStore.edit().clear().commit() | ||
} | ||
|
||
companion object { | ||
private const val ACCESS_TOKEN = "ACCESS_TOKEN" | ||
private const val REFRESH_TOKEN = "REFRESH_TOKEN" | ||
private const val USER_ID = "USER_ID" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.terning.data.repositoryimpl | ||
|
||
import com.terning.data.datasource.AuthDataSource | ||
import com.terning.data.dto.request.toSignInRequestDto | ||
import com.terning.domain.entity.request.SignInRequestModel | ||
import com.terning.domain.entity.response.SignInResponseModel | ||
import com.terning.domain.repository.AuthRepository | ||
import javax.inject.Inject | ||
|
||
class AuthRepositoryImpl @Inject constructor( | ||
private val authDataSource: AuthDataSource | ||
) : AuthRepository { | ||
override suspend fun postSignIn( | ||
authorization: String, | ||
request: SignInRequestModel | ||
): Result<SignInResponseModel> = kotlin.runCatching { | ||
authDataSource.postSignIn( | ||
authorization, | ||
request.toSignInRequestDto() | ||
).result.toSignInModel() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package com.terning.data.repositoryimpl | ||
|
||
import com.terning.data.datasource.CalendarDataSource | ||
import com.terning.data.dto.request.CalendarDayListRequestDto | ||
import com.terning.data.dto.request.CalendarMonthListRequestDto | ||
import com.terning.data.dto.request.CalendarMonthRequestDto | ||
import com.terning.domain.entity.response.CalendarScrapDetailModel | ||
import com.terning.domain.entity.response.CalendarScrapModel | ||
import com.terning.domain.repository.CalendarRepository | ||
import java.time.LocalDate | ||
import java.time.format.DateTimeFormatter | ||
import javax.inject.Inject | ||
|
||
class CalendarRepositoryImpl @Inject constructor( | ||
private val calendarDataSource: CalendarDataSource | ||
) : CalendarRepository { | ||
override suspend fun getScrapMonth( | ||
year: Int, | ||
month: Int | ||
): Result<Map<String, List<CalendarScrapModel>>> = | ||
runCatching { | ||
val result = calendarDataSource.getCalendarMonth( | ||
request = CalendarMonthRequestDto( | ||
year = year, | ||
month = month | ||
) | ||
).result | ||
|
||
val scrapModelMapByDeadLine = result.flatMap { dto -> | ||
dto.toScrapModelList() | ||
}.groupBy { it.deadLine } | ||
|
||
scrapModelMapByDeadLine | ||
} | ||
|
||
override suspend fun getScrapMonthList( | ||
year: Int, | ||
month: Int | ||
): Result<Map<String, List<CalendarScrapDetailModel>>> = | ||
runCatching { | ||
val result = calendarDataSource.getCalendarMonthList( | ||
request = CalendarMonthListRequestDto( | ||
year = year, | ||
month = month | ||
) | ||
).result | ||
|
||
val scrapModelMapByDeadLine = result.flatMap { dto -> | ||
dto.toScrapDetailModelList() | ||
}.groupBy { it.deadLine } | ||
|
||
scrapModelMapByDeadLine | ||
} | ||
|
||
override suspend fun getScrapDayList( | ||
currentDate: LocalDate | ||
): Result<List<CalendarScrapDetailModel>> = | ||
runCatching { | ||
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") | ||
val request = CalendarDayListRequestDto(currentDate.format(formatter)) | ||
val response = calendarDataSource.getCalendarDayList(request) | ||
val scrapModelList = response.result.map { scrap -> | ||
scrap.toScrapDetailModelList() | ||
} | ||
scrapModelList | ||
} | ||
} |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.terning.data.repositoryimpl | ||
|
||
import com.terning.data.datasource.SearchDataSource | ||
import com.terning.domain.entity.response.InternshipAnnouncement | ||
import com.terning.domain.repository.SearchRepository | ||
import javax.inject.Inject | ||
|
||
class SearchViewsRepositoryImpl @Inject constructor( | ||
private val searchDataSource: SearchDataSource, | ||
) : SearchRepository { | ||
override suspend fun getSearchViewsList(): Result<List<InternshipAnnouncement>> = | ||
runCatching { | ||
searchDataSource.getSearchViews().result.toSearchViewsEntity() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.terning.data.repositoryimpl | ||
|
||
import com.terning.data.local.TerningDataStore | ||
import com.terning.domain.repository.TokenRepository | ||
import javax.inject.Inject | ||
|
||
class TokenRepositoryImpl @Inject constructor( | ||
private val terningDataStore: TerningDataStore | ||
) : TokenRepository { | ||
override fun getAccessToken(): String = terningDataStore.accessToken | ||
|
||
override fun getRefreshToken(): String = terningDataStore.refreshToken | ||
|
||
override fun setTokens(accessToken: String, refreshToken: String) { | ||
terningDataStore.accessToken = accessToken | ||
terningDataStore.refreshToken = refreshToken | ||
} | ||
|
||
override fun setUserId(userId: Long) { | ||
terningDataStore.userId = userId | ||
} | ||
|
||
override fun clearInfo() { | ||
terningDataStore.clearInfo() | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.terning.data.service | ||
|
||
import com.terning.data.dto.BaseResponse | ||
import com.terning.data.dto.request.SignInRequestDto | ||
import com.terning.data.dto.response.SignInResponseDto | ||
import retrofit2.http.Body | ||
import retrofit2.http.Header | ||
import retrofit2.http.POST | ||
|
||
interface AuthService { | ||
@POST("api/v1/auth/sign-in") | ||
suspend fun postSignIn( | ||
@Header("Authorization") authorization: String, | ||
@Body body: SignInRequestDto, | ||
): BaseResponse<SignInResponseDto> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.terning.data.service | ||
|
||
import com.terning.data.dto.BaseResponse | ||
import com.terning.data.dto.response.CalendarMonthListResponseDto | ||
import com.terning.data.dto.response.CalendarMonthResponseDto | ||
import retrofit2.http.GET | ||
import retrofit2.http.Query | ||
|
||
interface CalendarService{ | ||
@GET("/api/v1/calendar/monthly-default") | ||
suspend fun getCalendarScrapMonth( | ||
@Query("year") year: Int, | ||
@Query("month") month: Int | ||
): BaseResponse<List<CalendarMonthResponseDto>> | ||
|
||
@GET("/api/v1/calendar/monthly-list") | ||
suspend fun getCalendarScrapMonthList( | ||
@Query("year") year: Int, | ||
@Query("month") month: Int | ||
): BaseResponse<List<CalendarMonthListResponseDto>> | ||
|
||
@GET("/api/v1/calendar/daily") | ||
suspend fun getCalendarScrapDayList( | ||
@Query("year") year: Int, | ||
@Query("month") month: Int, | ||
@Query("day") day: Int | ||
): BaseResponse<List<CalendarMonthListResponseDto>> | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.terning.data.service | ||
|
||
import com.terning.data.dto.BaseResponse | ||
import com.terning.data.dto.response.SearchViewsResponseDto | ||
import retrofit2.http.GET | ||
|
||
interface SearchService { | ||
@GET("api/v1/search/views") | ||
suspend fun getSearchViewsList(): BaseResponse<SearchViewsResponseDto> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.terning.domain.entity.request | ||
|
||
data class SignInRequestModel( | ||
val authType: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.terning.domain.entity.response | ||
|
||
data class CalendarScrapDetailModel( | ||
val scrapId: Long, | ||
val internshipAnnouncementId: Long, | ||
val title: String, | ||
val dDay: String, | ||
val workingPeriod: String, | ||
val color: String, | ||
val companyImage: String, | ||
val startYear: Int, | ||
val startMonth: Int, | ||
val deadLine: String, | ||
val isScrapped: Boolean = true | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.terning.domain.entity.response | ||
|
||
data class InternshipAnnouncement( | ||
val title: String, | ||
val companyImage: String, | ||
val announcementId: Long, | ||
) |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.terning.domain.entity.response | ||
|
||
data class SignInResponseModel( | ||
val accessToken : String? , | ||
val refreshToken : String?, | ||
val userId : Long, | ||
val authType: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.terning.domain.repository | ||
|
||
import com.terning.domain.entity.request.SignInRequestModel | ||
import com.terning.domain.entity.response.SignInResponseModel | ||
|
||
interface AuthRepository { | ||
suspend fun postSignIn( | ||
authorization: String, | ||
request: SignInRequestModel | ||
): Result<SignInResponseModel> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.terning.domain.repository | ||
|
||
import com.terning.domain.entity.response.CalendarScrapDetailModel | ||
import com.terning.domain.entity.response.CalendarScrapModel | ||
import java.time.LocalDate | ||
|
||
interface CalendarRepository{ | ||
suspend fun getScrapMonth(year: Int, month: Int): Result<Map<String, List<CalendarScrapModel>>> | ||
suspend fun getScrapMonthList(year: Int, month: Int): Result<Map<String,List<CalendarScrapDetailModel>>> | ||
suspend fun getScrapDayList(currentDate: LocalDate): Result<List<CalendarScrapDetailModel>> | ||
} |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.terning.domain.repository | ||
|
||
import com.terning.domain.entity.response.InternshipAnnouncement | ||
|
||
interface SearchRepository { | ||
suspend fun getSearchViewsList(): Result<List<InternshipAnnouncement>> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.terning.domain.repository | ||
|
||
interface TokenRepository { | ||
fun getAccessToken(): String | ||
|
||
fun getRefreshToken(): String | ||
|
||
fun setTokens(accessToken: String, refreshToken: String) | ||
|
||
fun setUserId(userId: Long) | ||
|
||
fun clearInfo() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.terning.feature.calendar.month | ||
|
||
import com.terning.core.state.UiState | ||
import com.terning.domain.entity.response.CalendarScrapModel | ||
|
||
data class CalendarMonthState ( | ||
val loadState: UiState<Map<String, List<CalendarScrapModel>>> = UiState.Loading | ||
) |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package com.terning.feature.calendar.scrap | ||
|
||
import androidx.compose.foundation.background | ||
import androidx.compose.foundation.layout.Box | ||
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.foundation.lazy.LazyColumn | ||
import androidx.compose.foundation.lazy.LazyListState | ||
import androidx.compose.foundation.lazy.LazyRow | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.LaunchedEffect | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.snapshotFlow | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.text.style.TextAlign | ||
import androidx.compose.ui.unit.dp | ||
import androidx.hilt.navigation.compose.hiltViewModel | ||
import androidx.lifecycle.compose.LocalLifecycleOwner | ||
import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||
import com.terning.core.designsystem.theme.Back | ||
import com.terning.core.designsystem.theme.Grey400 | ||
import com.terning.core.designsystem.theme.TerningTheme | ||
import com.terning.core.designsystem.theme.White | ||
import com.terning.core.extension.getDateAsMapString | ||
import com.terning.core.extension.isListNotEmpty | ||
import com.terning.core.state.UiState | ||
import com.terning.feature.R | ||
import com.terning.feature.calendar.calendar.CalendarViewModel | ||
import com.terning.feature.calendar.calendar.model.CalendarDefaults.flingBehavior | ||
import com.terning.feature.calendar.calendar.model.CalendarState.Companion.getDateByPage | ||
import com.terning.feature.calendar.scrap.component.CalendarScrapList | ||
import kotlinx.coroutines.flow.distinctUntilChanged | ||
import java.time.LocalDate | ||
|
||
@Composable | ||
fun CalendarListScreen( | ||
pages: Int, | ||
listState: LazyListState, | ||
modifier: Modifier = Modifier, | ||
viewModel: CalendarViewModel = hiltViewModel() | ||
) { | ||
val lifecycleOwner = LocalLifecycleOwner.current | ||
val scrapState by viewModel.calendarListState.collectAsStateWithLifecycle(lifecycleOwner) | ||
|
||
LaunchedEffect(key1 = listState) { | ||
snapshotFlow { listState.firstVisibleItemIndex } | ||
.distinctUntilChanged() | ||
.collect { | ||
val page = listState.firstVisibleItemIndex | ||
val date = getDateByPage(page) | ||
viewModel.getScrapMonthList(date.year, date.monthValue) | ||
} | ||
} | ||
|
||
|
||
LazyRow( | ||
modifier = modifier | ||
.background(White), | ||
state = listState, | ||
userScrollEnabled = true, | ||
flingBehavior = flingBehavior( | ||
state = listState | ||
) | ||
) { | ||
items(pages) { page -> | ||
val getDate = getDateByPage(page) | ||
|
||
LazyColumn( | ||
modifier = Modifier | ||
.fillParentMaxWidth() | ||
.fillMaxHeight() | ||
.background(Back) | ||
) { | ||
when (scrapState.loadState) { | ||
UiState.Loading -> {} | ||
UiState.Empty -> { | ||
item { | ||
Box( | ||
modifier = Modifier.fillMaxSize(), | ||
contentAlignment = Alignment.Center | ||
) { | ||
Text( | ||
modifier = Modifier | ||
.padding(top = 42.dp) | ||
.fillMaxWidth(), | ||
text = stringResource(id = R.string.calendar_empty_scrap), | ||
textAlign = TextAlign.Center, | ||
style = TerningTheme.typography.body5, | ||
color = Grey400 | ||
) | ||
} | ||
} | ||
} | ||
|
||
is UiState.Failure -> {} | ||
is UiState.Success -> { | ||
items(getDate.lengthOfMonth()) { day -> | ||
val scrapMap = (scrapState.loadState as UiState.Success).data | ||
val currentDate = | ||
LocalDate.of(getDate.year, getDate.monthValue, day + 1) | ||
val dateIndex = currentDate.getDateAsMapString() | ||
|
||
if (scrapMap[dateIndex].isListNotEmpty()) { | ||
CalendarScrapList( | ||
selectedDate = currentDate, | ||
scrapList = scrapMap[dateIndex].orEmpty(), | ||
isFromList = true, | ||
|
||
noScrapScreen = {}) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.terning.feature.calendar.scrap | ||
|
||
import com.terning.core.state.UiState | ||
import com.terning.domain.entity.response.CalendarScrapDetailModel | ||
|
||
data class CalendarListState ( | ||
val loadState: UiState<Map<String, List<CalendarScrapDetailModel>>> = UiState.Loading | ||
) |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.terning.feature.calendar.scrap.component | ||
|
||
import androidx.compose.foundation.layout.Column | ||
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.rememberScrollState | ||
import androidx.compose.foundation.verticalScroll | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.unit.dp | ||
import com.terning.core.designsystem.theme.Black | ||
import com.terning.core.designsystem.theme.TerningTheme | ||
import com.terning.core.extension.getDateStringInKorean | ||
import com.terning.core.extension.isListNotEmpty | ||
import com.terning.domain.entity.response.CalendarScrapDetailModel | ||
import java.time.LocalDate | ||
|
||
@Composable | ||
fun CalendarScrapList( | ||
selectedDate: LocalDate, | ||
scrapList: List<CalendarScrapDetailModel>, | ||
isFromList: Boolean = false, | ||
noScrapScreen: @Composable () -> Unit | ||
) { | ||
val scrollState = rememberScrollState() | ||
|
||
if (scrapList.isListNotEmpty()) { | ||
Text( | ||
text = selectedDate.getDateStringInKorean(), | ||
style = TerningTheme.typography.title5, | ||
color = Black, | ||
modifier = Modifier.padding(start = 24.dp, top = 16.dp, bottom = 15.dp) | ||
) | ||
} | ||
val topModifier = if (!isFromList) { | ||
Modifier | ||
.fillMaxWidth() | ||
.padding(horizontal = 24.dp) | ||
.verticalScroll(scrollState) | ||
} else { | ||
Modifier | ||
.fillMaxWidth() | ||
.padding(horizontal = 24.dp) | ||
} | ||
|
||
if (!scrapList.isListNotEmpty()) { | ||
noScrapScreen() | ||
} else { | ||
Column( | ||
modifier = topModifier | ||
) { | ||
for (scrap in scrapList) { | ||
CalendarScrap( | ||
scrap = scrap | ||
) | ||
Spacer( | ||
modifier = Modifier.height(12.dp) | ||
) | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package com.terning.feature.calendar.week | ||
|
||
import androidx.compose.foundation.background | ||
import androidx.compose.foundation.border | ||
import androidx.compose.foundation.layout.Box | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.shape.RoundedCornerShape | ||
import androidx.compose.material3.Card | ||
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.draw.shadow | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.text.style.TextAlign | ||
import androidx.compose.ui.unit.dp | ||
import androidx.hilt.navigation.compose.hiltViewModel | ||
import androidx.lifecycle.compose.LocalLifecycleOwner | ||
import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||
import com.terning.core.designsystem.theme.Back | ||
import com.terning.core.designsystem.theme.Grey200 | ||
import com.terning.core.designsystem.theme.Grey400 | ||
import com.terning.core.designsystem.theme.TerningTheme | ||
import com.terning.core.designsystem.theme.White | ||
import com.terning.core.state.UiState | ||
import com.terning.domain.entity.response.CalendarScrapDetailModel | ||
import com.terning.feature.R | ||
import com.terning.feature.calendar.calendar.CalendarViewModel | ||
import com.terning.feature.calendar.scrap.component.CalendarScrapList | ||
import java.time.LocalDate | ||
|
||
@Composable | ||
fun CalendarWeekScreen( | ||
modifier: Modifier = Modifier, | ||
viewModel: CalendarViewModel = hiltViewModel() | ||
) { | ||
val lifecycleOwner = LocalLifecycleOwner.current | ||
val uiState by viewModel.selectedDate.collectAsStateWithLifecycle(lifecycleOwner) | ||
val calendarWeekState by viewModel.calendarWeekState.collectAsStateWithLifecycle(lifecycleOwner) | ||
|
||
LaunchedEffect(uiState.selectedDate) { | ||
viewModel.getScrapWeekList() | ||
} | ||
|
||
Column( | ||
modifier = modifier | ||
.background(Back) | ||
) { | ||
Card( | ||
modifier = Modifier | ||
.border( | ||
width = 0.dp, | ||
color = Grey200, | ||
shape = RoundedCornerShape(bottomStart = 20.dp, bottomEnd = 20.dp) | ||
) | ||
.shadow( | ||
shape = RoundedCornerShape(bottomStart = 20.dp, bottomEnd = 20.dp), | ||
elevation = 1.dp | ||
), | ||
|
||
shape = RoundedCornerShape(bottomStart = 20.dp, bottomEnd = 20.dp), | ||
) { | ||
HorizontalCalendarWeek( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.background(White), | ||
selectedDate = uiState, | ||
onDateSelected = { | ||
viewModel.updateSelectedDate(it) | ||
} | ||
) | ||
} | ||
|
||
when (calendarWeekState.loadState) { | ||
is UiState.Loading -> {} | ||
is UiState.Empty -> { | ||
CalendarWeekEmpty() | ||
} | ||
is UiState.Failure -> {} | ||
is UiState.Success -> { | ||
val scrapList = (calendarWeekState.loadState as UiState.Success).data | ||
CalendarWeekSuccess(scrapList = scrapList, selectedDate = uiState.selectedDate) | ||
} | ||
} | ||
} | ||
} | ||
|
||
@Composable | ||
fun CalendarWeekEmpty( | ||
modifier: Modifier = Modifier | ||
) { | ||
Box( | ||
contentAlignment = Alignment.Center | ||
) { | ||
|
||
|
||
Text( | ||
modifier = Modifier | ||
.padding(top = 42.dp) | ||
.fillMaxWidth(), | ||
text = stringResource(id = R.string.calendar_empty_scrap), | ||
textAlign = TextAlign.Center, | ||
style = TerningTheme.typography.body5, | ||
color = Grey400 | ||
) | ||
} | ||
} | ||
|
||
@Composable | ||
fun CalendarWeekSuccess( | ||
scrapList: List<CalendarScrapDetailModel>, | ||
selectedDate: LocalDate, | ||
) { | ||
|
||
CalendarScrapList(selectedDate = selectedDate, scrapList = scrapList) {} | ||
} | ||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.terning.feature.calendar.week | ||
|
||
import com.terning.core.state.UiState | ||
import com.terning.domain.entity.response.CalendarScrapDetailModel | ||
|
||
data class CalendarWeekState ( | ||
val loadState: UiState<List<CalendarScrapDetailModel>> = UiState.Loading | ||
) |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,11 @@ | ||
package com.terning.feature.mypage | ||
|
||
import androidx.lifecycle.ViewModel | ||
import com.terning.domain.repository.MockRepository | ||
import dagger.hilt.android.lifecycle.HiltViewModel | ||
import javax.inject.Inject | ||
|
||
@HiltViewModel | ||
class MyPageViewModel @Inject constructor(private val repository: MockRepository) : ViewModel() { | ||
class MyPageViewModel @Inject constructor() : ViewModel() { | ||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.terning.feature.search.search | ||
|
||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import com.terning.core.state.UiState | ||
import com.terning.domain.repository.SearchRepository | ||
import com.terning.feature.R | ||
import dagger.hilt.android.lifecycle.HiltViewModel | ||
import kotlinx.coroutines.flow.MutableSharedFlow | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.StateFlow | ||
import kotlinx.coroutines.flow.asSharedFlow | ||
import kotlinx.coroutines.flow.asStateFlow | ||
import kotlinx.coroutines.launch | ||
import javax.inject.Inject | ||
|
||
@HiltViewModel | ||
class SearchViewModel @Inject constructor( | ||
private val searchRepository: SearchRepository, | ||
) : ViewModel() { | ||
private val _state: MutableStateFlow<SearchViewsState> = MutableStateFlow(SearchViewsState()) | ||
val state: StateFlow<SearchViewsState> = _state.asStateFlow() | ||
|
||
private val _sideEffect: MutableSharedFlow<SearchViewsSideEffect> = MutableSharedFlow() | ||
val sideEffect = _sideEffect.asSharedFlow() | ||
|
||
init { | ||
getSearchViews() | ||
} | ||
|
||
fun getSearchViews() { | ||
viewModelScope.launch { | ||
searchRepository.getSearchViewsList().onSuccess { searchViewsList -> | ||
_state.value = _state.value.copy( | ||
searchViewsList = UiState.Success(searchViewsList) | ||
) | ||
}.onFailure { | ||
_sideEffect.emit(SearchViewsSideEffect.Toast(R.string.server_failure)) | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.terning.feature.search.search | ||
|
||
import androidx.annotation.StringRes | ||
|
||
sealed class SearchViewsSideEffect { | ||
data class Toast(@StringRes val message: Int) : SearchViewsSideEffect() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.terning.feature.search.search | ||
|
||
import com.terning.core.state.UiState | ||
import com.terning.domain.entity.response.InternshipAnnouncement | ||
|
||
data class SearchViewsState( | ||
var searchViewsList: UiState<List<InternshipAnnouncement>> = UiState.Loading, | ||
) |