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/organization/20 organization create flow UI #26

Merged
merged 19 commits into from
Jul 20, 2024
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
51 changes: 46 additions & 5 deletions app/src/main/java/com/easyhz/noffice/NofficeApp.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
package com.easyhz.noffice

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.FabPosition
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.NavHost
import androidx.navigation.navOptions
import com.easyhz.noffice.core.design_system.component.bottomBar.HomeBottomBar
import com.easyhz.noffice.core.design_system.component.button.HomeAddButton
import com.easyhz.noffice.core.design_system.component.scaffold.NofficeScaffold
import com.easyhz.noffice.navigation.home.homeScreen
import com.easyhz.noffice.navigation.home.navigateToHome
import com.easyhz.noffice.navigation.home.screen.Home
import com.easyhz.noffice.navigation.organization.navigateToOrganizationCreation
import com.easyhz.noffice.navigation.organization.navigateToOrganizationInvitation
import com.easyhz.noffice.navigation.organization.organizationScreen
import com.easyhz.noffice.navigation.rememberNofficeNavController
import com.easyhz.noffice.navigation.sign.screen.SignUp
import com.easyhz.noffice.navigation.sign.signScreen
import com.easyhz.noffice.navigation.util.BOTTOM_BAR_DURATION
import com.easyhz.noffice.navigation.util.BottomMenuTabs

@Composable
Expand All @@ -27,15 +36,35 @@ fun NofficeApp() {

NofficeScaffold(
floatingActionButton = {
if(isVisibleBottomBar) {
AnimatedVisibility(
visible = isVisibleBottomBar,
enter = slideInVertically(
initialOffsetY = { it },
animationSpec = tween(durationMillis = BOTTOM_BAR_DURATION)
),
exit = slideOutVertically(
targetOffsetY = { it + 52 },
animationSpec = tween(durationMillis = BOTTOM_BAR_DURATION)
)
) {
HomeAddButton(
modifier = Modifier.offset(y = 52.dp)
) { }
}
},
floatingActionButtonPosition = FabPosition.Center,
bottomBar = {
if(isVisibleBottomBar) {
AnimatedVisibility(
visible = isVisibleBottomBar,
enter = slideInVertically(
initialOffsetY = { it },
animationSpec = tween(durationMillis = BOTTOM_BAR_DURATION)
),
exit = slideOutVertically(
targetOffsetY = { it },
animationSpec = tween(durationMillis = BOTTOM_BAR_DURATION)
)
) {
HomeBottomBar(
tabs = enumValues<BottomMenuTabs>(),
current = currentTab,
Expand All @@ -45,10 +74,22 @@ fun NofficeApp() {
}
) {
NavHost(
navController = navController, startDestination = SignUp
navController = navController, startDestination = Home
) {
homeScreen(modifier = Modifier.padding(it))
organizationScreen(modifier = Modifier.padding(it))
organizationScreen(
modifier = Modifier.padding(it),
navigateToCreation = navController::navigateToOrganizationCreation,
navigateToInvitation = navController::navigateToOrganizationInvitation,
navigateToHome = {
val navOptions = navOptions {
popUpTo(navController.graph.id) {
inclusive = true
}
}
navController.navigateToHome(navOptions)
}
)
signScreen()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ internal class NofficeNavController(
fun isInBottomTabs(): Boolean = currentRoute in routes

@Composable
fun mapRouteToTab(): BottomMenuTabs {
fun mapRouteToTab(): BottomMenuTabs? {
return when (currentRoute) {
Home::class.java.name -> BottomMenuTabs.HOME
// Add::class.java.name -> BottomMenuTabs.ADD // FIXME
Organization::class.java.name -> BottomMenuTabs.ORGANIZATION
else -> BottomMenuTabs.HOME
else -> null
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,75 @@
package com.easyhz.noffice.navigation.organization

import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.core.tween
import androidx.compose.ui.Modifier
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import androidx.navigation.navOptions
import androidx.navigation.toRoute
import com.easyhz.noffice.feature.organization.screen.creation.OrganizationCreationScreen
import com.easyhz.noffice.feature.organization.screen.invitation.OrganizationInvitationScreen
import com.easyhz.noffice.feature.organization.screen.organization.OrganizationScreen
import com.easyhz.noffice.navigation.organization.screen.Organization
import com.easyhz.noffice.navigation.organization.screen.OrganizationCreation
import com.easyhz.noffice.navigation.organization.screen.OrganizationInvitation
import com.easyhz.noffice.navigation.util.DURATION

internal fun NavGraphBuilder.organizationScreen(modifier: Modifier) {
internal fun NavGraphBuilder.organizationScreen(
modifier: Modifier,
navigateToCreation: () -> Unit,
navigateToInvitation: (String, String)-> Unit,
navigateToHome: () -> Unit
) {
composable<Organization> {
OrganizationScreen(modifier = modifier)
OrganizationScreen(
modifier = modifier,
navigateToCreation = navigateToCreation
)
}
composable<OrganizationCreation>(
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, tween(DURATION)) },
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, tween(DURATION)) },
popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.End, tween(DURATION)) },
popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End, tween(DURATION)) }
) {
OrganizationCreationScreen(
navigateToInvitation = navigateToInvitation,
navigateToHome = navigateToHome
)
}
composable<OrganizationInvitation>(
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, tween(DURATION)) },
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, tween(DURATION)) },
popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.End, tween(DURATION)) },
popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End, tween(DURATION)) }
) {
val args = it.toRoute<OrganizationInvitation>()
OrganizationInvitationScreen(
invitationUrl = args.invitationUrl,
imageUrl = args.imageUrl,
navigateToHome = navigateToHome
)
}

}

internal fun NavController.navigateToOrganization(navOptions: NavOptions) {
navigate(
route = Organization,
navOptions = navOptions
)
}

internal fun NavController.navigateToOrganizationCreation() {
navigate(OrganizationCreation)
}

internal fun NavController.navigateToOrganizationInvitation(invitationUrl: String, imageUrl: String) {
val navOptions = navOptions {
popUpTo(OrganizationCreation) { inclusive = true }
}
navigate(OrganizationInvitation(invitationUrl = invitationUrl, imageUrl = imageUrl), navOptions)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.easyhz.noffice.navigation.organization.screen

import kotlinx.serialization.Serializable

@Serializable
object OrganizationCreation
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.easyhz.noffice.navigation.organization.screen

import kotlinx.serialization.Serializable

@Serializable
data class OrganizationInvitation(
val invitationUrl: String,
val imageUrl: String = "",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.easyhz.noffice.navigation.util

const val DURATION = 500
const val BOTTOM_BAR_DURATION = 300
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.easyhz.noffice.core.common.util

import java.time.LocalDate
import java.time.format.DateTimeFormatter

object DateFormat {
fun fullText(date: LocalDate): String =
DateTimeFormatter.ofPattern("yyyy년 MM월 d일").format(date)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.easyhz.noffice.core.common.util

import java.util.EnumMap

data class Step<T>(
val currentStep: T,
val previousStep: T?
)
interface StepRequired {
val isRequired: Boolean
}
inline fun <reified T> List<T>.toEnabledStepButton(): EnumMap<T, Boolean> where T: Enum<T>, T: StepRequired =
EnumMap<T, Boolean>(T::class.java).apply {
[email protected] { step ->
this[step] = !step.isRequired
}
}

fun <T> EnumMap<T, Boolean>.updateStepButton(key: T, isEnabled: Boolean): EnumMap<T, Boolean>
where T: Enum<T> {
this[key] = isEnabled
return this
}
3 changes: 3 additions & 0 deletions core/design-system/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ dependencies {

// Glide
implementation(libs.glide)

// Calendar
implementation(libs.calendar.compose)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import com.easyhz.noffice.core.design_system.util.bottomBar.BottomMenu
@Composable
fun <T> HomeBottomBar(
modifier: Modifier = Modifier,
current: T,
current: T?,
tabs: Array<T>,
onClick: (T) -> Unit,
) where T: Enum<T>, T: BottomMenu {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.easyhz.noffice.core.design_system.R
Expand All @@ -38,6 +39,7 @@ import com.easyhz.noffice.core.design_system.theme.Grey600
@Composable
fun CheckButton(
modifier: Modifier = Modifier,
textAlign: TextAlign = TextAlign.Start,
text: String,
isComplete: Boolean,
color: CheckButtonDefaults = CheckButtonDefaults.default(),
Expand All @@ -52,7 +54,7 @@ fun CheckButton(
.heightIn(min = 42.dp)
.clip(RoundedCornerShape(8.dp))
.background(if (isComplete) color.completeContainerColor else color.incompleteContainerColor)
.padding(vertical = 10.dp)
.padding(vertical = 14.dp)
.screenHorizonPadding(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(10.dp)
Expand All @@ -61,13 +63,14 @@ fun CheckButton(
modifier = Modifier.weight(1f),
text = text,
color = if(isComplete) color.completeContentColor else color.incompleteContentColor,
style = Body14
style = Body14,
textAlign = textAlign
)
if (isComplete || color.incompleteIconColor != null) {
if ((isComplete && color.completeIconColor != null) || color.incompleteIconColor != null) {
Icon(
painter = painterResource(id = R.drawable.ic_check),
contentDescription = "check",
tint = if (isComplete) color.completeIconColor else color.incompleteIconColor ?: color.completeIconColor
tint = (if (isComplete) color.completeIconColor else color.incompleteIconColor) ?: color.completeContentColor
)
}
}
Expand All @@ -79,7 +82,7 @@ fun CheckButton(
data class CheckButtonDefaults(
val completeContainerColor: Color,
val completeContentColor: Color,
val completeIconColor: Color,
val completeIconColor: Color?,
val incompleteContainerColor: Color,
val incompleteContentColor: Color,
val incompleteIconColor: Color?,
Expand Down Expand Up @@ -187,3 +190,24 @@ private fun CheckButtonOrganizationCompletePrev() {
}


@Preview(group = "checkButton", name = "organization - complete")
@Composable
private fun CheckButtonOrganizationCompleteNullPrev() {
CheckButton(
modifier = Modifier.width(300.dp),
text = "CMC 15th",
isComplete = true,
color = CheckButtonDefaults(
completeContainerColor = Green100,
completeContentColor = Green700,
completeIconColor = null,
incompleteContainerColor = Grey50,
incompleteContentColor = Grey600,
incompleteIconColor = null
)
) {

}
}


Loading