diff --git a/core/designsystem/src/main/java/com/goalpanzi/mission_mate/core/designsystem/ext/Modifier.kt b/core/designsystem/src/main/java/com/goalpanzi/mission_mate/core/designsystem/ext/Modifier.kt new file mode 100644 index 00000000..f4195ba7 --- /dev/null +++ b/core/designsystem/src/main/java/com/goalpanzi/mission_mate/core/designsystem/ext/Modifier.kt @@ -0,0 +1,42 @@ +package com.goalpanzi.mission_mate.core.designsystem.ext + +import android.graphics.BlurMaskFilter +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Paint +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.graphics.drawOutline +import androidx.compose.ui.graphics.drawscope.drawIntoCanvas +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +fun Modifier.dropShadow( + shape: Shape, + color: Color = Color.Black.copy(0.1f), + blur: Dp = 4.dp, + offsetY: Dp = 0.dp, + offsetX: Dp = 0.dp, + spread: Dp = 0.dp +) = this.drawBehind { + + val shadowSize = Size(size.width + spread.toPx(), size.height + spread.toPx()) + val shadowOutline = shape.createOutline(shadowSize, layoutDirection, this) + + val paint = Paint() + paint.color = color + + if (blur.toPx() > 0) { + paint.asFrameworkPaint().apply { + maskFilter = BlurMaskFilter(blur.toPx(), BlurMaskFilter.Blur.NORMAL) + } + } + + drawIntoCanvas { canvas -> + canvas.save() + canvas.translate(offsetX.toPx(), offsetY.toPx()) + canvas.drawOutline(shadowOutline, paint) + canvas.restore() + } +} \ No newline at end of file diff --git a/core/designsystem/src/main/res/drawable/background_jeju.png b/core/designsystem/src/main/res/drawable/background_jeju.png new file mode 100644 index 00000000..b9c2f1b4 Binary files /dev/null and b/core/designsystem/src/main/res/drawable/background_jeju.png differ diff --git a/core/designsystem/src/main/res/drawable/background_jeju_theme.png b/core/designsystem/src/main/res/drawable/background_jeju_theme.png new file mode 100644 index 00000000..a1fd5147 Binary files /dev/null and b/core/designsystem/src/main/res/drawable/background_jeju_theme.png differ diff --git a/core/designsystem/src/main/res/drawable/ic_creating_board.xml b/core/designsystem/src/main/res/drawable/ic_creating_board.xml new file mode 100644 index 00000000..57d2aa51 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_creating_board.xml @@ -0,0 +1,10 @@ + + + diff --git a/core/designsystem/src/main/res/drawable/ic_invitation_friend.xml b/core/designsystem/src/main/res/drawable/ic_invitation_friend.xml new file mode 100644 index 00000000..7ce3efb8 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_invitation_friend.xml @@ -0,0 +1,25 @@ + + + + + + diff --git a/core/designsystem/src/main/res/drawable/ic_setting.xml b/core/designsystem/src/main/res/drawable/ic_setting.xml new file mode 100644 index 00000000..cbe860e1 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_setting.xml @@ -0,0 +1,10 @@ + + + diff --git a/core/designsystem/src/main/res/drawable/image_onboarding_jeju.png b/core/designsystem/src/main/res/drawable/image_onboarding_jeju.png new file mode 100644 index 00000000..71af63aa Binary files /dev/null and b/core/designsystem/src/main/res/drawable/image_onboarding_jeju.png differ diff --git a/core/navigation/src/main/java/com/goalpanzi/mission_mate/core/navigation/RouteModel.kt b/core/navigation/src/main/java/com/goalpanzi/mission_mate/core/navigation/RouteModel.kt index d0ad89be..7b36c68e 100644 --- a/core/navigation/src/main/java/com/goalpanzi/mission_mate/core/navigation/RouteModel.kt +++ b/core/navigation/src/main/java/com/goalpanzi/mission_mate/core/navigation/RouteModel.kt @@ -5,4 +5,15 @@ import kotlinx.serialization.Serializable sealed interface RouteModel { @Serializable data object Login : RouteModel + + @Serializable + data object Onboarding : RouteModel +} + +sealed interface OnboardingRouteModel { + @Serializable + data object BoardSetup : OnboardingRouteModel + + @Serializable + data object InvitationCode : OnboardingRouteModel } \ No newline at end of file diff --git a/feature/main/build.gradle.kts b/feature/main/build.gradle.kts index dba8b50c..a6a0df44 100644 --- a/feature/main/build.gradle.kts +++ b/feature/main/build.gradle.kts @@ -70,4 +70,5 @@ dependencies { implementation(project(":core:navigation")) implementation(project(":core:domain")) implementation(project(":feature:login")) + implementation(project(":feature:onboarding")) } \ No newline at end of file diff --git a/feature/main/src/main/java/com/goalpanzi/mission_mate/core/main/component/MainNavHost.kt b/feature/main/src/main/java/com/goalpanzi/mission_mate/core/main/component/MainNavHost.kt index d76c4a9c..fc0cb642 100644 --- a/feature/main/src/main/java/com/goalpanzi/mission_mate/core/main/component/MainNavHost.kt +++ b/feature/main/src/main/java/com/goalpanzi/mission_mate/core/main/component/MainNavHost.kt @@ -9,6 +9,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.navigation.compose.NavHost import com.goalpanzi.mission_mate.feature.login.loginNavGraph +import com.goalpanzi.mission_mate.feature.onboarding.boardSetupNavGraph +import com.goalpanzi.mission_mate.feature.onboarding.invitationCodeNavGraph +import com.goalpanzi.mission_mate.feature.onboarding.onboardingNavGraph @Composable internal fun MainNavHost( @@ -28,6 +31,13 @@ internal fun MainNavHost( loginNavGraph( onBackClick = { navigator.popBackStack() } ) + onboardingNavGraph( + onClickBoardSetup = { }, + onClickInvitationCode = { }, + onClickSetting = { } + ) + boardSetupNavGraph() + invitationCodeNavGraph() } } } \ No newline at end of file diff --git a/feature/main/src/main/java/com/goalpanzi/mission_mate/core/main/component/MainNavigator.kt b/feature/main/src/main/java/com/goalpanzi/mission_mate/core/main/component/MainNavigator.kt index 20f8eaaf..7e4ca198 100644 --- a/feature/main/src/main/java/com/goalpanzi/mission_mate/core/main/component/MainNavigator.kt +++ b/feature/main/src/main/java/com/goalpanzi/mission_mate/core/main/component/MainNavigator.kt @@ -6,6 +6,9 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController import com.goalpanzi.mission_mate.core.navigation.RouteModel import com.goalpanzi.mission_mate.feature.login.navigateToLogin +import com.goalpanzi.mission_mate.feature.onboarding.navigateToBoardSetup +import com.goalpanzi.mission_mate.feature.onboarding.navigateToInvitationCode +import com.goalpanzi.mission_mate.feature.onboarding.navigateToOnboarding class MainNavigator( val navController: NavHostController @@ -21,6 +24,18 @@ class MainNavigator( fun navigateToLogin() { navController.navigateToLogin() } + + fun navigationToOnboarding() { + navController.navigateToOnboarding() + } + + fun navigationToBoardSetup() { + navController.navigateToBoardSetup() + } + + fun navigationToInvitationCode() { + navController.navigateToInvitationCode() + } } @Composable diff --git a/feature/onboarding/.gitignore b/feature/onboarding/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/onboarding/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/onboarding/build.gradle.kts b/feature/onboarding/build.gradle.kts new file mode 100644 index 00000000..9e30fb5f --- /dev/null +++ b/feature/onboarding/build.gradle.kts @@ -0,0 +1,70 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.jetbrains.kotlin.android) + alias(libs.plugins.compose.compiler) + alias(libs.plugins.kotlin.ksp) + alias(libs.plugins.hilt.android) +} + +android { + namespace = "com.goalpanzi.mission_mate.feature.onboarding" + compileSdk = 34 + + defaultConfig { + minSdk = 26 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } + buildFeatures { + compose = true + } + composeCompiler { + enableStrongSkippingMode = true + } +} + +dependencies { + + implementation(libs.androidx.core.ktx) + implementation(libs.bundles.lifecycle) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.bundles.compose) + implementation(libs.bundles.coroutines) + + testImplementation(libs.bundles.test) + androidTestImplementation(libs.bundles.android.test) + androidTestImplementation(platform(libs.androidx.compose.bom)) + debugImplementation(libs.androidx.ui.tooling) + debugImplementation(libs.androidx.ui.test.manifest) + + implementation(libs.androidx.hilt.navigation.compose) + implementation(libs.hilt.android) + ksp(libs.hilt.compiler) + + implementation(libs.coil.compose) + + implementation(project(":core:designsystem")) + implementation(project(":core:navigation")) +} \ No newline at end of file diff --git a/feature/onboarding/consumer-rules.pro b/feature/onboarding/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/feature/onboarding/proguard-rules.pro b/feature/onboarding/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/feature/onboarding/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/feature/onboarding/src/androidTest/java/com/goalpanzi/mission_mate/feature/onboarding/ExampleInstrumentedTest.kt b/feature/onboarding/src/androidTest/java/com/goalpanzi/mission_mate/feature/onboarding/ExampleInstrumentedTest.kt new file mode 100644 index 00000000..4e1b6ca9 --- /dev/null +++ b/feature/onboarding/src/androidTest/java/com/goalpanzi/mission_mate/feature/onboarding/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.goalpanzi.mission_mate.feature.onboarding + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.goalpanzi.mission_mate.feature.onboarding.test", appContext.packageName) + } +} \ No newline at end of file diff --git a/feature/onboarding/src/main/AndroidManifest.xml b/feature/onboarding/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a5918e68 --- /dev/null +++ b/feature/onboarding/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/OnboardingNavigation.kt b/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/OnboardingNavigation.kt new file mode 100644 index 00000000..6d29deb4 --- /dev/null +++ b/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/OnboardingNavigation.kt @@ -0,0 +1,45 @@ +package com.goalpanzi.mission_mate.feature.onboarding + +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable +import com.goalpanzi.mission_mate.core.navigation.OnboardingRouteModel +import com.goalpanzi.mission_mate.core.navigation.RouteModel + +fun NavController.navigateToOnboarding() { + this.navigate(RouteModel.Onboarding) +} + +fun NavController.navigateToBoardSetup() { + this.navigate(OnboardingRouteModel.BoardSetup) +} + +fun NavController.navigateToInvitationCode() { + this.navigate(OnboardingRouteModel.InvitationCode) +} + +fun NavGraphBuilder.onboardingNavGraph( + onClickBoardSetup : () -> Unit, + onClickInvitationCode : () -> Unit, + onClickSetting : () -> Unit +) { + composable { + OnboardingRoute( + onClickBoardSetup = onClickBoardSetup, + onClickInvitationCode = onClickInvitationCode, + onClickSetting = onClickSetting + ) + } +} + +fun NavGraphBuilder.boardSetupNavGraph() { + composable { + + } +} + +fun NavGraphBuilder.invitationCodeNavGraph() { + composable { + + } +} \ No newline at end of file diff --git a/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/OnboardingScreen.kt b/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/OnboardingScreen.kt new file mode 100644 index 00000000..a1e430a9 --- /dev/null +++ b/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/OnboardingScreen.kt @@ -0,0 +1,138 @@ +package com.goalpanzi.mission_mate.feature.onboarding + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +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.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import com.goalpanzi.mission_mate.core.designsystem.theme.ColorGray1_FF404249 +import com.goalpanzi.mission_mate.core.designsystem.theme.ColorWhite_FFFFFFFF +import com.goalpanzi.mission_mate.core.designsystem.theme.MissionMateTypography +import com.goalpanzi.mission_mate.feature.onboarding.component.OnboardingNavigationButton +import com.goalpanzi.mission_mate.feature.onboarding.component.OutlinedTextBox +import com.goalpanzi.mission_mate.feature.onboarding.component.StableImage +import com.goalpanzi.mission_mate.core.designsystem.R as designSystemResource + +@Composable +fun OnboardingRoute( + modifier: Modifier = Modifier, + onClickBoardSetup : () -> Unit, + onClickInvitationCode : () -> Unit, + onClickSetting : () -> Unit +) { + OnboardingScreen( + modifier = modifier.fillMaxSize(), + onClickBoardSetup = onClickBoardSetup, + onClickInvitationCode = onClickInvitationCode, + onClickSetting = onClickSetting + ) +} + +@Composable +fun OnboardingScreen( + modifier: Modifier = Modifier, + onClickBoardSetup : () -> Unit, + onClickInvitationCode : () -> Unit, + onClickSetting : () -> Unit +) { + Box( + modifier = modifier.background(ColorWhite_FFFFFFFF) + ) { + Image( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight(), + painter = painterResource(id = designSystemResource.drawable.background_jeju), + contentDescription = null, + contentScale = ContentScale.FillWidth + ) + Column( + modifier = modifier, + horizontalAlignment = Alignment.CenterHorizontally + ) { + IconButton( + modifier = Modifier + .padding(end = 10.dp, top = 24.dp) + .align(Alignment.End), + onClick = onClickSetting + ) { + Icon( + painter = painterResource(id = designSystemResource.drawable.ic_setting), + contentDescription = null + ) + } + Text( + modifier = Modifier.padding(bottom = 52.dp), + text = stringResource(id = R.string.onboarding_ready_title), + textAlign = TextAlign.Center, + style = MissionMateTypography.heading_sm_regular, + color = ColorGray1_FF404249 + ) + OutlinedTextBox( + text = stringResource(id = R.string.onboarding_level_1), + modifier = Modifier.padding(bottom = 23.dp) + ) + Box( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 7.dp) + .wrapContentHeight(), + contentAlignment = Alignment.BottomCenter + ) { + StableImage( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight(), + drawableResId = designSystemResource.drawable.background_jeju_theme, + contentScale = ContentScale.FillWidth + ) + StableImage( + modifier = Modifier + .fillMaxWidth(0.564f) + .wrapContentHeight(), + drawableResId = designSystemResource.drawable.img_rabbit_selected, + contentScale = ContentScale.FillWidth + ) + } + Row( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 24.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(18.dp) + ) { + OnboardingNavigationButton( + modifier = Modifier.weight(1f), + titleId = R.string.onboarding_crating_board_title, + descriptionId = R.string.onboarding_crating_board_desription, + imageId = designSystemResource.drawable.ic_creating_board, + onClick = onClickBoardSetup + ) + OnboardingNavigationButton( + modifier = Modifier.weight(1f), + titleId = R.string.onboarding_code_title, + descriptionId = R.string.onboarding_code_desription, + imageId = designSystemResource.drawable.ic_invitation_friend, + onClick = onClickInvitationCode + ) + } + } + } + +} diff --git a/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/component/OnboardingNavigationButton.kt b/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/component/OnboardingNavigationButton.kt new file mode 100644 index 00000000..f69f73a6 --- /dev/null +++ b/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/component/OnboardingNavigationButton.kt @@ -0,0 +1,67 @@ +package com.goalpanzi.mission_mate.feature.onboarding.component + +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ElevatedButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.goalpanzi.mission_mate.core.designsystem.ext.dropShadow +import com.goalpanzi.mission_mate.core.designsystem.theme.ColorGray1_FF404249 +import com.goalpanzi.mission_mate.core.designsystem.theme.ColorGray3_FF727484 +import com.goalpanzi.mission_mate.core.designsystem.theme.ColorWhite_FFFFFFFF +import com.goalpanzi.mission_mate.core.designsystem.theme.MissionMateTypography + +@Composable +fun OnboardingNavigationButton( + @StringRes titleId : Int, + @StringRes descriptionId : Int, + @DrawableRes imageId: Int, + onClick : () -> Unit, + modifier: Modifier = Modifier, + shape: Shape = RoundedCornerShape(20.dp) +){ + ElevatedButton( + modifier = modifier.dropShadow(shape), + onClick = onClick, + shape = shape, + colors = ButtonDefaults.elevatedButtonColors( + containerColor = ColorWhite_FFFFFFFF + ), + contentPadding = PaddingValues() + ) { + Column( + modifier = Modifier, + verticalArrangement = Arrangement.spacedBy(6.dp) + ) { + Text( + modifier = Modifier.padding(start = 20.dp, end = 20.dp,top = 20.dp), + text = stringResource(id = titleId), + style = MissionMateTypography.title_xl_bold, + color = ColorGray1_FF404249 + ) + Text( + modifier = Modifier.padding(start = 20.dp, end = 20.dp, bottom = 12.dp), + text = stringResource(id = descriptionId), + style = MissionMateTypography.body_lg_regular, + color = ColorGray3_FF727484 + ) + StableImage( + modifier = Modifier + .padding(bottom = 12.dp, end = 8.dp) + .align(Alignment.End), + drawableResId = imageId + ) + } + } +} \ No newline at end of file diff --git a/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/component/OutlinedBox.kt b/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/component/OutlinedBox.kt new file mode 100644 index 00000000..528c5198 --- /dev/null +++ b/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/component/OutlinedBox.kt @@ -0,0 +1,44 @@ +package com.goalpanzi.mission_mate.feature.onboarding.component + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.dp +import com.goalpanzi.mission_mate.core.designsystem.theme.ColorOrange_FFFF5732 +import com.goalpanzi.mission_mate.core.designsystem.theme.MissionMateTypography + +@Composable +fun OutlinedTextBox( + text : String, + modifier: Modifier = Modifier, + borderStroke: BorderStroke = BorderStroke(1.dp, ColorOrange_FFFF5732), + shape: Shape = RoundedCornerShape(50), + contentPadding : PaddingValues = PaddingValues(vertical = 1.dp, horizontal = 14.dp), + textStyle: TextStyle = MissionMateTypography.title_lg_regular, + textColor : Color = ColorOrange_FFFF5732 +){ + Box( + modifier = modifier + .border(borderStroke, shape) + .padding(contentPadding), + contentAlignment = Alignment.Center + ){ + Text( + text = text, + style = textStyle, + color = textColor + ) + } +} \ No newline at end of file diff --git a/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/component/StableImage.kt b/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/component/StableImage.kt new file mode 100644 index 00000000..7f657642 --- /dev/null +++ b/feature/onboarding/src/main/java/com/goalpanzi/mission_mate/feature/onboarding/component/StableImage.kt @@ -0,0 +1,24 @@ +package com.goalpanzi.mission_mate.feature.onboarding.component + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.Image +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource + +@Composable +fun StableImage ( + @DrawableRes drawableResId: Int, + modifier: Modifier = Modifier, + contentScale: ContentScale = ContentScale.Fit, + description : String? = null, +) { + val painter = painterResource(id = drawableResId) + Image( + modifier = modifier, + painter = painter, + contentScale = contentScale, + contentDescription = description + ) +} \ No newline at end of file diff --git a/feature/onboarding/src/main/res/values/strings.xml b/feature/onboarding/src/main/res/values/strings.xml new file mode 100644 index 00000000..0392472e --- /dev/null +++ b/feature/onboarding/src/main/res/values/strings.xml @@ -0,0 +1,10 @@ + + + 미션 완수를 위해\n경쟁할 준비가 되었나요? + 미션보드\n생성하기 + 내 목표는 내가~ + 초대코드\n입력하기 + 초대받고 왔지~ + + LV1. 제주도 + \ No newline at end of file diff --git a/feature/onboarding/src/test/java/com/goalpanzi/mission_mate/feature/onboarding/ExampleUnitTest.kt b/feature/onboarding/src/test/java/com/goalpanzi/mission_mate/feature/onboarding/ExampleUnitTest.kt new file mode 100644 index 00000000..9bab1c85 --- /dev/null +++ b/feature/onboarding/src/test/java/com/goalpanzi/mission_mate/feature/onboarding/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.goalpanzi.mission_mate.feature.onboarding + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dc40b48a..e4bbee1f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -108,6 +108,7 @@ credentials-auth = { group = "androidx.credentials", name = "credentials-play-se google-id = { group = "com.google.android.libraries.identity.googleid", name = "googleid", version = "identity" } material = { group = "com.google.android.material", name = "material", version.ref = "material" } + [plugins] ## Android gradle plugin android-application = { id = "com.android.application", version.ref = "agp" } diff --git a/settings.gradle.kts b/settings.gradle.kts index c5bf1a21..a6c442f9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -31,3 +31,4 @@ include(":feature:login") include(":feature:main") include(":feature:board") include(":core:model") +include(":feature:onboarding")