Skip to content
Open
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
@@ -0,0 +1,88 @@
package com.woocommerce.android.ui.woopos.orders

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.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import com.woocommerce.android.R
import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosDialogWrapper
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosText
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosSpacing
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTheme
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTypography

@Composable
fun WooPosIssueRefundDialog(
isVisible: Boolean,
orderId: Long,
onDismissRequest: () -> Unit
) {
WooPosDialogWrapper(
isVisible = isVisible,
dialogBackgroundContentDescription = stringResource(
R.string.woopos_orders_issue_refund_content_description
),
onDismissRequest = onDismissRequest
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(WooPosSpacing.Large.value),
horizontalAlignment = Alignment.CenterHorizontally
) {
IconButton(
onClick = onDismissRequest,
modifier = Modifier.align(Alignment.End)
) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(R.string.close),
tint = MaterialTheme.colorScheme.onSurface
)
}

Spacer(Modifier.height(WooPosSpacing.Medium.value))

WooPosText(
text = stringResource(R.string.orderdetail_issue_refund_button),
style = WooPosTypography.Heading,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSurface
)

Spacer(Modifier.height(WooPosSpacing.Large.value))

WooPosText(
text = "Refund flow coming soon for order #$orderId",
style = WooPosTypography.BodyMedium,
color = WooPosTheme.colors.onSurfaceVariantHighest
)

Spacer(Modifier.height(WooPosSpacing.Large.value))
}
}
}

@WooPosPreview
@Composable
fun WooPosIssueRefundDialogPreview() {
WooPosTheme {
WooPosIssueRefundDialog(
isVisible = true,
orderId = 123L,
onDismissRequest = {}
)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.woocommerce.android.ui.woopos.orders

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
Expand All @@ -16,9 +18,18 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Inventory2
import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
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,7 +54,9 @@ import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTyp
fun WooPosOrderDetails(
modifier: Modifier = Modifier,
details: OrderDetailsViewState.Computed.Details,
onEmailReceiptButtonClicked: (Long) -> Unit
actions: List<OrderAction>,
onEmailReceiptButtonClicked: (Long) -> Unit,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it's the final state or still WIP, but this is not something that is driven by the VM as you have to pass hardcoded click listeners here and everywhere instead of calling one onUIEvent that accepts events that are part of the “actions”. Also, why is OrderAction not part of the whole state but a separate class?

onIssueRefundButtonClicked: (Long) -> Unit
) {
Column(
modifier = modifier
Expand All @@ -53,7 +66,6 @@ fun WooPosOrderDetails(
.padding(
start = WooPosSpacing.Medium.value,
end = WooPosSpacing.Medium.value,
top = WooPosSpacing.XLarge.value,
bottom = WooPosSpacing.XLarge.value
)
) {
Expand All @@ -69,10 +81,34 @@ fun WooPosOrderDetails(

Spacer(Modifier.weight(1f))

WooPosButtonSmall(
text = stringResource(R.string.woopos_orders_email_receipt),
onClick = { onEmailReceiptButtonClicked(details.id) },
)
when {
actions.size > 1 -> {
val primaryAction = actions.first()
val overflowActions = actions.drop(1)

OrderActionButton(
action = primaryAction,
onIssueRefundClicked = onIssueRefundButtonClicked,
onEmailReceiptClicked = onEmailReceiptButtonClicked
)

Spacer(Modifier.width(WooPosSpacing.Small.value))

OrderDetailsOverflowMenu(
actions = overflowActions,
onIssueRefundClicked = onIssueRefundButtonClicked,
onEmailReceiptClicked = onEmailReceiptButtonClicked
)
}

actions.size == 1 -> {
OrderActionButton(
action = actions.first(),
onIssueRefundClicked = onIssueRefundButtonClicked,
onEmailReceiptClicked = onEmailReceiptButtonClicked
)
}
}
}

Spacer(Modifier.height(WooPosSpacing.Small.value))
Expand Down Expand Up @@ -333,6 +369,75 @@ private fun DividerWithSpacing() {
Spacer(Modifier.height(WooPosSpacing.Medium.value))
}

@Composable
private fun OrderActionButton(
action: OrderAction,
onIssueRefundClicked: (Long) -> Unit,
onEmailReceiptClicked: (Long) -> Unit
) {
when (action) {
is OrderAction.IssueRefund -> {
WooPosButtonSmall(
text = stringResource(R.string.orderdetail_issue_refund_button),
onClick = { onIssueRefundClicked(action.orderId) }
)
}
is OrderAction.EmailReceipt -> {
WooPosButtonSmall(
text = stringResource(R.string.woopos_orders_email_receipt),
onClick = { onEmailReceiptClicked(action.orderId) }
)
}
}
}

@Composable
private fun OrderDetailsOverflowMenu(
actions: List<OrderAction>,
onIssueRefundClicked: (Long) -> Unit,
onEmailReceiptClicked: (Long) -> Unit
) {
var showMenu by remember { mutableStateOf(false) }

Box {
IconButton(onClick = { showMenu = true }) {
Icon(
imageVector = Icons.Outlined.MoreVert,
contentDescription = stringResource(R.string.more_menu),
tint = MaterialTheme.colorScheme.onSurface
)
}

DropdownMenu(
modifier = Modifier.background(color = MaterialTheme.colorScheme.surfaceContainerLowest),
expanded = showMenu,
onDismissRequest = { showMenu = false }
) {
actions.forEach { action ->
DropdownMenuItem(
text = {
val text = when (action) {
is OrderAction.IssueRefund -> stringResource(R.string.orderdetail_issue_refund_button)
is OrderAction.EmailReceipt -> stringResource(R.string.woopos_orders_email_receipt)
}
WooPosText(
text = text,
style = WooPosTypography.BodyMedium
)
},
onClick = {
showMenu = false
when (action) {
is OrderAction.IssueRefund -> onIssueRefundClicked(action.orderId)
is OrderAction.EmailReceipt -> onEmailReceiptClicked(action.orderId)
}
}
)
}
}
}
}

@WooPosPreview
@Composable
fun WooPosOrderDetailsPreview() {
Expand Down Expand Up @@ -371,7 +476,12 @@ fun WooPosOrderDetailsPreview() {
WooPosTheme {
WooPosOrderDetails(
details = orderDetails,
onEmailReceiptButtonClicked = {}
actions = listOf(
OrderAction.IssueRefund(1L),
OrderAction.EmailReceipt(1L)
),
onEmailReceiptButtonClicked = {},
onIssueRefundButtonClicked = {}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ fun WooPosOrdersScreen(
onSearchErrorRetry = viewModel::onSearchErrorRetry,
onOrdersEmptyActionClicked = viewModel::onOrdersEmptyActionClicked,
onOrdersLoadingErrorRetryButtonClicked = viewModel::onOrdersLoadingErrorRetryButtonClicked,
onEmailReceiptButtonClicked = viewModel::onEmailReceiptButtonClicked
onEmailReceiptButtonClicked = viewModel::onEmailReceiptButtonClicked,
onIssueRefundButtonClicked = viewModel::onIssueRefundButtonClicked,
onIssueRefundDialogDismissed = viewModel::onIssueRefundDialogDismissed
)
}

Expand All @@ -127,6 +129,8 @@ private fun WooPosOrdersScreen(
onOrdersEmptyActionClicked: () -> Unit,
onOrdersLoadingErrorRetryButtonClicked: () -> Unit,
onEmailReceiptButtonClicked: (Long) -> Unit,
onIssueRefundButtonClicked: (Long) -> Unit,
onIssueRefundDialogDismissed: () -> Unit,
) {
BackHandler { onBackClicked() }

Expand All @@ -141,7 +145,9 @@ private fun WooPosOrdersScreen(
onPaginationErrorTryAgain = onPaginationErrorTryAgain,
onSearchEvent = onSearchEvent,
onSearchErrorRetry = onSearchErrorRetry,
onEmailReceiptButtonClicked = onEmailReceiptButtonClicked
onEmailReceiptButtonClicked = onEmailReceiptButtonClicked,
onIssueRefundButtonClicked = onIssueRefundButtonClicked,
onIssueRefundDialogDismissed = onIssueRefundDialogDismissed
)

is WooPosOrdersState.Empty -> OrdersEmpty(
Expand Down Expand Up @@ -175,7 +181,9 @@ private fun OrdersContent(
onPaginationErrorTryAgain: () -> Unit,
onSearchEvent: (WooPosSearchUIEvent) -> Unit,
onSearchErrorRetry: () -> Unit,
onEmailReceiptButtonClicked: (Long) -> Unit
onEmailReceiptButtonClicked: (Long) -> Unit,
onIssueRefundButtonClicked: (Long) -> Unit,
onIssueRefundDialogDismissed: () -> Unit
) {
Row(modifier = Modifier.fillMaxSize()) {
OrdersListPane(
Expand Down Expand Up @@ -203,9 +211,22 @@ private fun OrdersContent(
modifier = Modifier
.fillMaxHeight(),
details = state.selectedDetails,
onEmailReceiptButtonClicked = onEmailReceiptButtonClicked
actions = state.actions,
onEmailReceiptButtonClicked = onEmailReceiptButtonClicked,
onIssueRefundButtonClicked = onIssueRefundButtonClicked
)
}
}

when (val dialogState = state.dialogState) {
is WooPosOrdersState.Content.DialogState.IssueRefund -> {
WooPosIssueRefundDialog(
isVisible = true,
orderId = dialogState.orderId,
onDismissRequest = onIssueRefundDialogDismissed
)
}
WooPosOrdersState.Content.DialogState.Hidden -> Unit
}
}

Expand Down Expand Up @@ -564,7 +585,9 @@ fun WooPosOrdersScreenPreview() {
onSearchErrorRetry = {},
onOrdersEmptyActionClicked = {},
onOrdersLoadingErrorRetryButtonClicked = {},
onEmailReceiptButtonClicked = {}
onEmailReceiptButtonClicked = {},
onIssueRefundButtonClicked = {},
onIssueRefundDialogDismissed = {}
)
}
}
Expand Down Expand Up @@ -598,7 +621,9 @@ fun WooPosOrdersSearchErrorStatePreview() {
onSearchErrorRetry = {},
onOrdersEmptyActionClicked = {},
onOrdersLoadingErrorRetryButtonClicked = {},
onEmailReceiptButtonClicked = {}
onEmailReceiptButtonClicked = {},
onIssueRefundButtonClicked = {},
onIssueRefundDialogDismissed = {}
)
}
}
Expand Down Expand Up @@ -632,7 +657,9 @@ fun WooPosOrdersNothingFoundStatePreview() {
onSearchErrorRetry = {},
onOrdersEmptyActionClicked = {},
onOrdersLoadingErrorRetryButtonClicked = {},
onEmailReceiptButtonClicked = {}
onEmailReceiptButtonClicked = {},
onIssueRefundButtonClicked = {},
onIssueRefundDialogDismissed = {}
)
}
}
Expand Down
Loading
Loading