diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/budget/BlazeCampaignBudgetFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/budget/BlazeCampaignBudgetFragment.kt new file mode 100644 index 00000000000..79f87a6ce89 --- /dev/null +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/budget/BlazeCampaignBudgetFragment.kt @@ -0,0 +1,40 @@ +package com.woocommerce.android.ui.blaze.creation.budget + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.viewModels +import androidx.navigation.fragment.findNavController +import com.woocommerce.android.ui.base.BaseFragment +import com.woocommerce.android.ui.compose.composeView +import com.woocommerce.android.ui.main.AppBarStatus +import com.woocommerce.android.viewmodel.MultiLiveEvent +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class BlazeCampaignBudgetFragment : BaseFragment() { + override val activityAppBarStatus: AppBarStatus + get() = AppBarStatus.Hidden + + val viewModel: BlazeCampaignBudgetViewModel by viewModels() + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + return composeView { + CampaignBudgetScreen(viewModel) + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupObservers() + } + + private fun setupObservers() { + viewModel.event.observe(viewLifecycleOwner) { event -> + when (event) { + is MultiLiveEvent.Event.Exit -> findNavController().popBackStack() + } + } + } +} diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/budget/BlazeCampaignBudgetScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/budget/BlazeCampaignBudgetScreen.kt new file mode 100644 index 00000000000..a85dec505ef --- /dev/null +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/budget/BlazeCampaignBudgetScreen.kt @@ -0,0 +1,90 @@ +package com.woocommerce.android.ui.blaze.creation.budget + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.MaterialTheme +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material.Scaffold +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons.Filled +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.res.stringResource +import com.woocommerce.android.R.dimen +import com.woocommerce.android.R.string +import com.woocommerce.android.ui.compose.component.Toolbar +import com.woocommerce.android.ui.compose.component.WCColoredButton +import com.woocommerce.android.ui.compose.component.WCModalBottomSheetLayout +import kotlinx.coroutines.launch + +@Composable +fun CampaignBudgetScreen(viewModel: BlazeCampaignBudgetViewModel) { + CampaignBudgetScreen( + onBackPressed = viewModel::onBackPressed + ) +} + +@OptIn(ExperimentalMaterialApi::class) +@Composable +private fun CampaignBudgetScreen( + onBackPressed: () -> Unit +) { + val coroutineScope = rememberCoroutineScope() + val modalSheetState = rememberModalBottomSheetState( + initialValue = ModalBottomSheetValue.Hidden, + confirmValueChange = { it != ModalBottomSheetValue.HalfExpanded } + ) + Scaffold( + topBar = { + Toolbar( + title = stringResource(id = string.blaze_campaign_budget_title), + onNavigationButtonClick = onBackPressed, + navigationIcon = Filled.ArrowBack + ) + }, + modifier = Modifier.background(MaterialTheme.colors.surface) + ) { paddingValues -> + WCModalBottomSheetLayout( + sheetState = modalSheetState, + sheetContent = { + DurationSheetContent( + durationInDays = 0, + onApplyTapped = { + coroutineScope.launch { modalSheetState.hide() } + } + ) + } + ) { + Column( + modifier = Modifier + .padding(paddingValues) + .background(MaterialTheme.colors.surface) + .padding(dimensionResource(id = dimen.major_100)) + ) { + // Budget content + } + } + } +} + +@Composable +private fun DurationSheetContent( + durationInDays: Int, + onApplyTapped: () -> Unit, + modifier: Modifier = Modifier +) { + Column( + modifier = modifier.verticalScroll(rememberScrollState()) + ) { + Text(text = "Current duration: $durationInDays") + WCColoredButton(onClick = onApplyTapped, text = "Apply") + } +} diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/budget/BlazeCampaignBudgetViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/budget/BlazeCampaignBudgetViewModel.kt new file mode 100644 index 00000000000..0414d2d4caa --- /dev/null +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/budget/BlazeCampaignBudgetViewModel.kt @@ -0,0 +1,17 @@ +package com.woocommerce.android.ui.blaze.creation.budget + +import androidx.lifecycle.SavedStateHandle +import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.Exit +import com.woocommerce.android.viewmodel.ScopedViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class BlazeCampaignBudgetViewModel @Inject constructor( + savedStateHandle: SavedStateHandle, +) : ScopedViewModel(savedStateHandle) { + + fun onBackPressed() { + triggerEvent(Exit) + } +} diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewFragment.kt index a3501a325c9..68d23c45cb8 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewFragment.kt @@ -6,12 +6,14 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController +import com.woocommerce.android.extensions.navigateSafely import com.woocommerce.android.ui.base.BaseFragment import com.woocommerce.android.ui.compose.composeView import com.woocommerce.android.ui.main.AppBarStatus import com.woocommerce.android.viewmodel.MultiLiveEvent import dagger.hilt.android.AndroidEntryPoint import ui.blaze.creation.preview.BlazeCampaignCreationPreviewViewModel +import ui.blaze.creation.preview.BlazeCampaignCreationPreviewViewModel.NavigateToBudgetScreen @AndroidEntryPoint class BlazeCampaignCreationPreviewFragment : BaseFragment() { @@ -35,6 +37,10 @@ class BlazeCampaignCreationPreviewFragment : BaseFragment() { viewModel.event.observe(viewLifecycleOwner) { event -> when (event) { is MultiLiveEvent.Event.Exit -> findNavController().popBackStack() + is NavigateToBudgetScreen -> findNavController().navigateSafely( + BlazeCampaignCreationPreviewFragmentDirections + .actionBlazeCampaignCreationPreviewFragmentToBlazeCampaignBudgetFragment() + ) } } } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewScreen.kt index 9aaab43bf22..8a4076b1b18 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewScreen.kt @@ -2,6 +2,7 @@ package com.woocommerce.android.ui.blaze.creation.preview import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.clickable import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -315,6 +316,7 @@ private fun CampaignPropertyItem( Row( modifier = modifier .fillMaxWidth() + .clickable { item.onItemSelected() } .padding( start = 16.dp, end = 16.dp, @@ -365,28 +367,34 @@ fun CampaignScreenPreview() { budget = CampaignDetailItemUi( displayTitle = stringResource(R.string.blaze_campaign_preview_details_budget), displayValue = "140 USD, 7 days from Jan 14", + onItemSelected = {}, ), targetDetails = listOf( CampaignDetailItemUi( displayTitle = stringResource(R.string.blaze_campaign_preview_details_language), displayValue = "English, Spanish", + onItemSelected = {}, ), CampaignDetailItemUi( displayTitle = stringResource(R.string.blaze_campaign_preview_details_devices), displayValue = "USA, Poland, Japan", + onItemSelected = {}, ), CampaignDetailItemUi( displayTitle = stringResource(R.string.blaze_campaign_preview_details_location), displayValue = "Samsung, Apple, Xiaomi", + onItemSelected = {}, ), CampaignDetailItemUi( displayTitle = stringResource(R.string.blaze_campaign_preview_details_interests), displayValue = "Fashion, Clothing, T-shirts", + onItemSelected = {}, ), ), destinationUrl = CampaignDetailItemUi( displayTitle = "Destination URL", displayValue = "https://www.myer.com.au/p/white-t-shirt-797334760-797334760", + onItemSelected = {}, maxLinesValue = 1, ) ) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewViewModel.kt index 196c7c41e15..d11dccf4766 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/preview/BlazeCampaignCreationPreviewViewModel.kt @@ -62,32 +62,38 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor( budget = CampaignDetailItemUi( displayTitle = resourceProvider.getString(R.string.blaze_campaign_preview_details_budget), displayValue = budget.toDisplayValue(), + onItemSelected = { triggerEvent(NavigateToBudgetScreen) }, ), targetDetails = listOf( CampaignDetailItemUi( displayTitle = resourceProvider.getString(R.string.blaze_campaign_preview_details_language), displayValue = languages.joinToString { it.name } .ifEmpty { resourceProvider.getString(R.string.blaze_campaign_preview_target_default_value) }, + onItemSelected = { /* TODO Add language selection */ }, ), CampaignDetailItemUi( displayTitle = resourceProvider.getString(R.string.blaze_campaign_preview_details_devices), displayValue = locations.joinToString { it.name } .ifEmpty { resourceProvider.getString(R.string.blaze_campaign_preview_target_default_value) }, + onItemSelected = { /* TODO Add devices selection */ }, ), CampaignDetailItemUi( displayTitle = resourceProvider.getString(R.string.blaze_campaign_preview_details_location), displayValue = devices.joinToString { it.name } .ifEmpty { resourceProvider.getString(R.string.blaze_campaign_preview_target_default_value) }, + onItemSelected = { /* TODO Add location selection */ }, ), CampaignDetailItemUi( displayTitle = resourceProvider.getString(R.string.blaze_campaign_preview_details_interests), displayValue = interests.joinToString { it.description } .ifEmpty { resourceProvider.getString(R.string.blaze_campaign_preview_target_default_value) }, + onItemSelected = { /* TODO Add interests selection */ }, ), ), destinationUrl = CampaignDetailItemUi( displayTitle = resourceProvider.getString(R.string.blaze_campaign_preview_details_destination_url), displayValue = targetUrl, + onItemSelected = { /* TODO Add destination url selection */ }, maxLinesValue = 1, ) ) @@ -127,6 +133,9 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor( data class CampaignDetailItemUi( val displayTitle: String, val displayValue: String, + val onItemSelected: () -> Unit, val maxLinesValue: Int? = null, ) + + object NavigateToBudgetScreen : MultiLiveEvent.Event() } diff --git a/WooCommerce/src/main/res/navigation/nav_graph_blaze_campaign_creation.xml b/WooCommerce/src/main/res/navigation/nav_graph_blaze_campaign_creation.xml index b6f53e6b76d..e310902d2e0 100644 --- a/WooCommerce/src/main/res/navigation/nav_graph_blaze_campaign_creation.xml +++ b/WooCommerce/src/main/res/navigation/nav_graph_blaze_campaign_creation.xml @@ -50,5 +50,12 @@ android:name="productId" android:defaultValue="-1L" app:argType="long" /> + + diff --git a/WooCommerce/src/main/res/values/strings.xml b/WooCommerce/src/main/res/values/strings.xml index 8e1af62fe3f..538adcde4a9 100644 --- a/WooCommerce/src/main/res/values/strings.xml +++ b/WooCommerce/src/main/res/values/strings.xml @@ -3838,6 +3838,11 @@ %1$s days from %2$s All + + Set your budget +