@@ -4,6 +4,7 @@ import androidx.activity.compose.BackHandler
44import androidx.compose.foundation.background
55import androidx.compose.foundation.clickable
66import androidx.compose.foundation.layout.Arrangement
7+ import androidx.compose.foundation.layout.Box
78import androidx.compose.foundation.layout.Column
89import androidx.compose.foundation.layout.PaddingValues
910import androidx.compose.foundation.layout.Row
@@ -14,6 +15,10 @@ import androidx.compose.foundation.layout.fillMaxWidth
1415import androidx.compose.foundation.layout.padding
1516import androidx.compose.foundation.lazy.LazyColumn
1617import androidx.compose.foundation.lazy.items
18+ import androidx.compose.material.ExperimentalMaterialApi
19+ import androidx.compose.material.pullrefresh.PullRefreshIndicator
20+ import androidx.compose.material.pullrefresh.pullRefresh
21+ import androidx.compose.material.pullrefresh.rememberPullRefreshState
1722import androidx.compose.material3.MaterialTheme
1823import androidx.compose.runtime.Composable
1924import androidx.compose.runtime.collectAsState
@@ -27,16 +32,16 @@ import androidx.compose.ui.semantics.semantics
2732import androidx.compose.ui.text.font.FontWeight
2833import androidx.hilt.navigation.compose.hiltViewModel
2934import com.woocommerce.android.R
30- import com.woocommerce.android.extensions.formatToDDMMMYYYY
31- import com.woocommerce.android.model.Order
3235import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview
3336import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosText
3437import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosToolbar
3538import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosSpacing
3639import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTheme
3740import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTypography
41+ import com.woocommerce.android.ui.woopos.home.items.WooPosPullToRefreshState
3842import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent
3943
44+ @OptIn(ExperimentalMaterialApi ::class )
4045@Composable
4146fun WooPosOrdersScreen (
4247 onNavigationEvent : (WooPosNavigationEvent ) -> Unit ,
@@ -48,19 +53,59 @@ fun WooPosOrdersScreen(
4853 BackHandler { onNavigationEvent(WooPosNavigationEvent .GoBack ) }
4954
5055 Row (modifier = Modifier .fillMaxSize()) {
51- Column (
56+ OrdersList (
57+ state = state,
58+ onBackClicked = onBackClicked,
59+ onRefresh = viewModel::onRefresh,
60+ isRefreshing = state.pullToRefreshState == WooPosPullToRefreshState .Refreshing ,
61+ onOrderSelected = viewModel::onOrderSelected,
5262 modifier = Modifier
5363 .weight(0.3f )
5464 .fillMaxHeight()
5565 .background(MaterialTheme .colorScheme.surface)
56- ) {
57- WooPosToolbar (
58- titleText = stringResource(R .string.woopos_orders_title),
59- onBackClicked = onBackClicked,
60- )
66+ )
67+
68+ OrderDetails (
69+ state = state,
70+ modifier = Modifier
71+ .weight(0.7f )
72+ .fillMaxHeight()
73+ .background(MaterialTheme .colorScheme.surfaceContainerLow)
74+ )
75+ }
76+ }
77+
78+ @OptIn(ExperimentalMaterialApi ::class )
79+ @Composable
80+ private fun OrdersList (
81+ state : WooPosOrdersState ,
82+ onBackClicked : () -> Unit ,
83+ onRefresh : () -> Unit ,
84+ isRefreshing : Boolean ,
85+ onOrderSelected : (Long ) -> Unit ,
86+ modifier : Modifier = Modifier
87+ ) {
88+ Column (modifier = modifier) {
89+ WooPosToolbar (
90+ titleText = stringResource(R .string.woopos_orders_title),
91+ onBackClicked = onBackClicked,
92+ )
93+
94+ val pullRefreshState = rememberPullRefreshState(
95+ refreshing = isRefreshing,
96+ onRefresh = onRefresh
97+ )
6198
62- when {
63- state.isLoading -> {
99+ Box (
100+ modifier = Modifier
101+ .fillMaxSize()
102+ .pullRefresh(
103+ pullRefreshState,
104+ enabled = state.pullToRefreshState != WooPosPullToRefreshState .Disabled
105+ )
106+ ) {
107+ when (state) {
108+ is WooPosOrdersState .Loading -> {
64109 Column (
65110 modifier = Modifier .fillMaxSize(),
66111 horizontalAlignment = Alignment .CenterHorizontally
@@ -73,56 +118,77 @@ fun WooPosOrdersScreen(
73118 )
74119 }
75120 }
76- state.error != null -> {
121+
122+ is WooPosOrdersState .Error -> {
77123 Column (
78124 modifier = Modifier .fillMaxSize(),
79125 horizontalAlignment = Alignment .CenterHorizontally
80126 ) {
81127 WooPosText (
82- text = state.error ? : stringResource( R .string.error_generic) ,
128+ text = state.message ,
83129 style = WooPosTypography .BodyMedium ,
84130 color = MaterialTheme .colorScheme.error,
85131 modifier = Modifier .padding(WooPosSpacing .Large .value)
86132 )
87133 }
88134 }
89- state.orders.isEmpty() -> {
135+
136+ is WooPosOrdersState .Empty -> {
90137 Column (
91138 modifier = Modifier .fillMaxSize(),
92139 horizontalAlignment = Alignment .CenterHorizontally
93140 ) {
94141 WooPosText (
95- text = " No Orders Found " ,
142+ text = " No orders found " ,
96143 style = WooPosTypography .BodyMedium ,
97144 color = MaterialTheme .colorScheme.onSurfaceVariant,
98145 modifier = Modifier .padding(WooPosSpacing .Large .value)
99146 )
100147 }
101148 }
102- else -> {
149+
150+ is WooPosOrdersState .Content -> {
103151 WooPosOrdersListPaneScreen (
104- orders = state.orders ,
152+ items = state.items ,
105153 selectedOrderId = state.selectedOrderId,
106- onOrderSelected = viewModel:: onOrderSelected,
154+ onOrderSelected = onOrderSelected,
107155 modifier = Modifier .fillMaxSize()
108156 )
109157 }
110158 }
159+
160+ PullRefreshIndicator (
161+ refreshing = isRefreshing,
162+ state = pullRefreshState,
163+ modifier = Modifier
164+ .align(Alignment .TopCenter )
165+ .padding(top = WooPosSpacing .XSmall .value),
166+ backgroundColor = MaterialTheme .colorScheme.surface,
167+ contentColor = MaterialTheme .colorScheme.primary
168+ )
111169 }
170+ }
171+ }
112172
113- WooPosOrdersDetailPaneScreen (
114- order = state.selectedOrder,
115- modifier = Modifier
116- .weight(0.7f )
117- .fillMaxHeight()
118- .background(MaterialTheme .colorScheme.surfaceContainerLow)
119- )
173+ @Composable
174+ private fun OrderDetails (
175+ state : WooPosOrdersState ,
176+ modifier : Modifier = Modifier
177+ ) {
178+ val selectedItem: OrderItemViewState ? = when (state) {
179+ is WooPosOrdersState .Content -> state.items.firstOrNull { it.id == state.selectedOrderId }
180+ else -> null
120181 }
182+
183+ WooPosOrdersDetailPaneScreen (
184+ selected = selectedItem,
185+ modifier = modifier.fillMaxSize()
186+ )
121187}
122188
123189@Composable
124190fun WooPosOrdersListPaneScreen (
125- orders : List <Order >,
191+ items : List <OrderItemViewState >,
126192 selectedOrderId : Long? ,
127193 onOrderSelected : (Long ) -> Unit ,
128194 modifier : Modifier = Modifier
@@ -131,14 +197,13 @@ fun WooPosOrdersListPaneScreen(
131197 modifier = modifier,
132198 contentPadding = PaddingValues (vertical = WooPosSpacing .XSmall .value)
133199 ) {
134- items(orders , key = { it.id }) { order ->
135- val isSelected = order .id == selectedOrderId
200+ items(items , key = { it.id }) { item ->
201+ val isSelected = item .id == selectedOrderId
136202 val background = if (isSelected) {
137203 MaterialTheme .colorScheme.primaryContainer
138204 } else {
139205 MaterialTheme .colorScheme.surface
140206 }
141-
142207 val foreground = if (isSelected) {
143208 MaterialTheme .colorScheme.onPrimaryContainer
144209 } else {
@@ -150,32 +215,21 @@ fun WooPosOrdersListPaneScreen(
150215 .fillMaxWidth()
151216 .clip(MaterialTheme .shapes.medium)
152217 .background(background)
153- .clickable { onOrderSelected(order .id) }
218+ .clickable { onOrderSelected(item .id) }
154219 .semantics { selected = isSelected }
155220 .padding(
156221 horizontal = WooPosSpacing .Medium .value,
157222 vertical = WooPosSpacing .Medium .value
158223 ),
159224 verticalAlignment = Alignment .Top
160225 ) {
161- Column (
162- verticalArrangement = Arrangement .spacedBy(WooPosSpacing .XSmall .value)
163- ) {
164- WooPosText (
165- " Order #${order.number} " ,
166- style = WooPosTypography .BodyMedium
167- )
168- WooPosText (
169- text = order.dateCreated.formatToDDMMMYYYY(),
170- style = WooPosTypography .BodySmall ,
171- color = foreground
172- )
226+ Column (verticalArrangement = Arrangement .spacedBy(WooPosSpacing .XSmall .value)) {
227+ WooPosText (item.title, style = WooPosTypography .BodyMedium , color = foreground)
228+ WooPosText (item.date, style = WooPosTypography .BodySmall , color = foreground)
173229 }
174-
175230 Spacer (Modifier .weight(1f ))
176-
177231 WooPosText (
178- text = " ${order .total} ${order.currency} " ,
232+ text = item .total,
179233 style = WooPosTypography .BodyMedium ,
180234 modifier = Modifier .alignByBaseline()
181235 )
@@ -186,29 +240,22 @@ fun WooPosOrdersListPaneScreen(
186240
187241@Composable
188242fun WooPosOrdersDetailPaneScreen (
189- order : Order ? ,
243+ selected : OrderItemViewState ? ,
190244 modifier : Modifier = Modifier
191245) {
192- Column (
193- modifier = modifier.fillMaxSize()
194- ) {
246+ Column (modifier = modifier.fillMaxSize()) {
195247 WooPosToolbar (
196- modifier = Modifier
197- .fillMaxWidth(),
198- titleText = " Order #${order?.number ? : " --" } " ,
248+ modifier = Modifier .fillMaxWidth(),
249+ titleText = selected?.title ? : " --" ,
199250 titleFontWeight = FontWeight .Bold
200251 )
201-
202252 Column (
203253 modifier = Modifier
204254 .fillMaxSize()
205- .padding(
206- start = WooPosSpacing .Large .value,
207- end = WooPosSpacing .Large .value,
208- )
255+ .padding(start = WooPosSpacing .Large .value, end = WooPosSpacing .Large .value)
209256 ) {
210257 WooPosText (
211- text = " Orders details will be displayed here" ,
258+ text = " Order details goes here" ,
212259 style = WooPosTypography .BodyMedium ,
213260 color = MaterialTheme .colorScheme.onSurfaceVariant
214261 )
@@ -219,9 +266,5 @@ fun WooPosOrdersDetailPaneScreen(
219266@WooPosPreview
220267@Composable
221268fun WooPosOrdersScreenPreview () {
222- WooPosTheme {
223- WooPosOrdersScreen (
224- onNavigationEvent = {}
225- )
226- }
269+ WooPosTheme { WooPosOrdersScreen (onNavigationEvent = {}) }
227270}
0 commit comments