Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 동행 모집 화면 UI 구성 및 화면 구현 #39

Merged
merged 22 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5358615
[refactor] Res 파일 각 feature 모듈 별로 관리하는 방식으로 refactoring
medi-jihun-lee Aug 28, 2024
a38e563
[feat] 동행 모집 모듈 추가
medi-jihun-lee Aug 28, 2024
777a1d9
[chore] font includeFontPadding 옵션 설정 제거
medi-jihun-lee Aug 28, 2024
dbaf3d3
[feat] 홈 화면 동행 모집 화면 연결
medi-jihun-lee Aug 28, 2024
2f05805
[feat] 동행 모집 화면 UI 구성 및 구현 1차 완성
medi-jihun-lee Aug 28, 2024
42795a0
[style] 동행 모집 화면 UI 구성 완료
medi-jihun-lee Aug 29, 2024
60425fc
[feat] 동행 모집 화면 체크 박스 로직 구현 완료
medi-jihun-lee Aug 30, 2024
1c894ec
[chore] main 모듈로 start Activity 변경
medi-jihun-lee Aug 31, 2024
6196cf2
[add] Wheel Pick Compose 라이브러리 의존성 추가
medi-jihun-lee Aug 31, 2024
e90ee5a
[style] 개인화 화면 디자인 변경 사항 반영
medi-jihun-lee Aug 31, 2024
e64aa0d
[refactor] 개인화 화면 컴포넌트 분리 및 프리뷰 구성
medi-jihun-lee Aug 31, 2024
b880d70
[style] Date, Time Picker BottomSheet UI 구성 및 화면 구현
medi-jihun-lee Aug 31, 2024
7b152a7
[feat] 동행 모집 화면 구현 완료
medi-jihun-lee Aug 31, 2024
a48993d
[chore] style check success
medi-jihun-lee Aug 31, 2024
9121d8d
[chore] TODO 추가
medi-jihun-lee Aug 31, 2024
d059f74
[feat] 작성 완료 버튼 활성화 validation 추가
easyhooon Sep 1, 2024
093af24
[fix] 텍스트필드 문제 해결
easyhooon Sep 1, 2024
1ebe0e5
[refactor] wheel picker 라이브러리 migration
easyhooon Sep 1, 2024
14e3083
[fix] LocalDate, Time 파싱 문제 해결
medi-jihun-lee Sep 2, 2024
ff6e7c9
[fix] DateTimePicker Dialog 로 변경
medi-jihun-lee Sep 2, 2024
01e192c
[fix] Wheel Picker 라이브러리 롤백
medi-jihun-lee Sep 2, 2024
f37b193
[feat] 탭바 뒤로가기 구현
medi-jihun-lee Sep 2, 2024
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
2 changes: 2 additions & 0 deletions core/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ dependencies {
implementations(
projects.core.domain,

libs.kotlinx.datetime,

libs.androidx.hilt.navigation.compose,

libs.timber,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.tripmate.android.core.common.extension

import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.Locale

fun LocalDate.formatToDate(): String {
val formatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일", Locale.KOREAN)
return this.format(formatter)
}

// fun LocalDate.formatToDate(): String {
// return "${year}년 ${monthNumber.toString().padStart(2, '0')}월 ${dayOfMonth.toString().padStart(2, '0')}일"
// }
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.tripmate.android.core.common.extension

import java.time.LocalTime
import java.time.format.DateTimeFormatter
import java.util.Locale

fun LocalTime.formatToTime(): String {
val formatter = DateTimeFormatter.ofPattern("a h시 mm분", Locale.KOREAN)
return this.format(formatter)
.replace("AM", "오전")
.replace("PM", "오후")
}

// fun LocalTime.formatToTime(): String {
// val period = if (hour < 12) "오전" else "오후"
// val adjustedHour = when {
// hour == 0 -> 12
// hour > 12 -> hour - 12
// else -> hour
// }
// return "$period ${adjustedHour}시 ${minute.toString().padStart(2, '0')}분"
// }
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.tripmate.android.core.common.extension

import java.time.LocalDate
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import java.util.Locale

fun String.parseToLocalDate(): LocalDate {
val formatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일", Locale.KOREAN)
return LocalDate.parse(this, formatter)
}

fun String.parseToLocalTime(): LocalTime {
val formattedString = this.replace("오전", "AM").replace("오후", "PM")
val formatter = DateTimeFormatter.ofPattern("a h시 mm분", Locale.ENGLISH)
return LocalTime.parse(formattedString, formatter)
}

// fun String.parseToLocalDate(): LocalDate {
// if (this.isBlank()) {
// return Clock.System.now().toLocalDateTime(TimeZone.of("Asia/Seoul")).date
// }
//
// require(this.matches(Regex("^\\d{4}년\\s*\\d{1,2}월\\s*\\d{1,2}일$"))) { "잘못된 날짜 형식: $this" }
//
// val (year, month, day) = this.split("년", "월", "일")
// .filter { it.isNotBlank() }
// .map { it.trim().toInt() }
// return LocalDate(year, month, day)
// }
//
// fun String.parseToLocalTime(): LocalTime {
// if (this.isBlank()) {
// // 빈 문자열인 경우 현재 시간 반환
// return Clock.System.now().toLocalDateTime(TimeZone.of("Asia/Seoul")).time
// }
//
// require(this.matches(Regex("^(오전|오후)\\s*\\d{1,2}시\\s*\\d{1,2}분$"))) { "잘못된 시간 형식: $this" }
//
// val (period, time) = this.split(" ", limit = 2)
// val (hour, minute) = time.split("시 ", "분")
// .filter { it.isNotBlank() }
// .map { it.trim().toInt() }
//
// require(hour in 1..12 && minute in 0..59) { "유효하지 않은 시간 또는 분: $this" }
//
// val adjustedHour = when {
// period == "오후" && hour != 12 -> hour + 12
// period == "오전" && hour == 12 -> 0
// else -> hour
// }
//
// return LocalTime(adjustedHour, minute)
// }
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package com.tripmate.android.core.data.di

import com.tripmate.android.core.data.repository.NotificationRepositoryImpl
import com.tripmate.android.core.data.repository.MapRepositoryImpl
import com.tripmate.android.core.data.repository.MateRepositoryImpl
import com.tripmate.android.domain.repository.PersonalizationRepository
import com.tripmate.android.core.data.repository.PersonalizationRepositoryImpl
import com.tripmate.android.domain.repository.NotificationRepository
import com.tripmate.android.domain.repository.MapRepository
import com.tripmate.android.domain.repository.MateRepository
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
Expand All @@ -27,4 +29,8 @@ internal abstract class RepositoryModule {
@Binds
@Singleton
abstract fun bindNotificationRepository(notificationRepositoryImpl: NotificationRepositoryImpl): NotificationRepository

@Binds
@Singleton
abstract fun bindMateRepository(mateRepositoryImpl: MateRepositoryImpl): MateRepository
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.tripmate.android.core.data.repository

import com.tripmate.android.core.datastore.PersonalizationDataSource
import com.tripmate.android.domain.repository.MateRepository
import javax.inject.Inject

internal class MateRepositoryImpl @Inject constructor(
private val personalizationDataSource: PersonalizationDataSource,
) : MateRepository {
override suspend fun checkPersonalizationCompletion(): Boolean {
return personalizationDataSource.checkPersonalizationCompletion()
}

override suspend fun completePersonalization(flag: Boolean) {
personalizationDataSource.completePersonalization(flag)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
import com.tripmate.android.core.designsystem.ComponentPreview
import com.tripmate.android.core.designsystem.R
import com.tripmate.android.core.designsystem.theme.Background02
import com.tripmate.android.core.designsystem.theme.Gray001
Expand Down Expand Up @@ -143,6 +142,7 @@ fun ServerErrorDialog(
cancelTextResId = null,
onCancelClick = {},
onConfirmClick = onRetryClick,
modifier = Modifier.padding(16.dp),
)
}
}
Expand All @@ -162,24 +162,6 @@ fun NetworkErrorDialog(
cancelTextResId = null,
onCancelClick = {},
onConfirmClick = onRetryClick,
)
}
}

@ComponentPreview
@Composable
fun TripMateDialogPreview() {
TripmateTheme {
TripmateDialog(
onDismissRequest = {},
titleResId = R.string.under_age_title,
iconResId = null,
iconDescription = "",
descriptionResId = R.string.under_age_description,
cancelTextResId = null,
confirmTextResId = R.string.under_age_confirm,
onCancelClick = {},
onConfirmClick = {},
modifier = Modifier.padding(16.dp),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import androidx.compose.foundation.BorderStroke
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.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
Expand All @@ -24,67 +26,72 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import com.tripmate.android.core.designsystem.ComponentPreview
import com.tripmate.android.core.designsystem.R
import com.tripmate.android.core.designsystem.theme.Error
import com.tripmate.android.core.designsystem.theme.Gray001
import com.tripmate.android.core.designsystem.theme.Gray006
import com.tripmate.android.core.designsystem.theme.Gray008
import com.tripmate.android.core.designsystem.theme.Small14_Reg
import com.tripmate.android.core.designsystem.theme.TripmateTheme
import com.tripmate.android.core.designsystem.theme.XSmall12_Reg

@Composable
fun TripmateTextField(
text: String,
onTextChange: (String) -> Unit,
@StringRes searchTextHintRes: Int,
clearText: () -> Unit,
modifier: Modifier = Modifier,
keyboardOptions: KeyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
clearText: () -> Unit = {},
errorText: String? = null,
backgroundColor: Color = Color.White,
textColor: Color = Gray001,
cornerShape: RoundedCornerShape = RoundedCornerShape(6.dp),
borderStroke: BorderStroke = BorderStroke(width = 1.dp, color = if (errorText != null) Error else Gray008),
multiline: Boolean = false,
maxLength: Int? = null,
isClearIconVisible: Boolean = false,
) {
Column(modifier = modifier) {
Column {
BasicTextField(
value = text,
onValueChange = onTextChange,
modifier = Modifier.height(52.dp),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Done,
),
onValueChange = { text ->
if (maxLength == null || text.length <= maxLength) {
onTextChange(text)
}
},
keyboardOptions = keyboardOptions,
textStyle = Small14_Reg.copy(color = textColor),
singleLine = true,
singleLine = !multiline,
decorationBox = { innerTextField ->
Row(
modifier = Modifier
modifier = modifier
.background(
color = backgroundColor,
shape = cornerShape,
)
.border(
border = borderStroke,
shape = cornerShape,
),
verticalAlignment = Alignment.CenterVertically,
)
.padding(vertical = if (multiline) 12.dp else 0.dp, horizontal = 12.dp),
verticalAlignment = if (multiline) Alignment.Top else Alignment.CenterVertically,
) {
Spacer(modifier = Modifier.width(20.dp))
Box(modifier = Modifier.weight(1f)) {
Box {
if (text.isEmpty()) {
Text(
text = stringResource(id = searchTextHintRes),
color = Gray006,
maxLines = 1,
style = Small14_Reg,
)
}
innerTextField()
}
Spacer(modifier = Modifier.weight(1f))
if (text.isNotEmpty()) {
if (text.isNotEmpty() && isClearIconVisible) {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.ic_clear_text),
contentDescription = "clear icon",
Expand All @@ -95,12 +102,15 @@ fun TripmateTextField(
},
)
}
Spacer(modifier = Modifier.width(20.dp))
}
},
)
Spacer(modifier = Modifier.height(4.dp))
Row {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
if (errorText != null) {
Spacer(modifier = Modifier.height(4.dp))
Text(
Expand All @@ -120,3 +130,15 @@ fun TripmateTextField(
}
}
}

@ComponentPreview
@Composable
fun TripmateTextFieldPreview() {
TripmateTheme {
TripmateTextField(
text = "트립메이트",
onTextChange = {},
searchTextHintRes = R.string.app_name,
)
}
}
Loading
Loading