17
17
package com.example.fruitties.android.ui
18
18
19
19
import androidx.compose.foundation.layout.Column
20
+ import androidx.compose.foundation.layout.Row
20
21
import androidx.compose.foundation.layout.Spacer
21
22
import androidx.compose.foundation.layout.WindowInsets
22
23
import androidx.compose.foundation.layout.WindowInsetsSides
24
+ import androidx.compose.foundation.layout.consumeWindowInsets
23
25
import androidx.compose.foundation.layout.fillMaxWidth
24
26
import androidx.compose.foundation.layout.only
25
27
import androidx.compose.foundation.layout.padding
26
28
import androidx.compose.foundation.layout.safeDrawing
27
29
import androidx.compose.foundation.layout.systemBars
30
+ import androidx.compose.foundation.layout.width
28
31
import androidx.compose.foundation.layout.windowInsetsBottomHeight
29
32
import androidx.compose.foundation.lazy.LazyColumn
30
33
import androidx.compose.foundation.lazy.items
31
34
import androidx.compose.material.icons.Icons
32
35
import androidx.compose.material.icons.automirrored.filled.ArrowBack
33
36
import androidx.compose.material3.CenterAlignedTopAppBar
34
37
import androidx.compose.material3.ExperimentalMaterial3Api
38
+ import androidx.compose.material3.FilledIconButton
39
+ import androidx.compose.material3.HorizontalDivider
35
40
import androidx.compose.material3.Icon
36
41
import androidx.compose.material3.IconButton
42
+ import androidx.compose.material3.IconButtonDefaults
37
43
import androidx.compose.material3.MaterialTheme
38
44
import androidx.compose.material3.Scaffold
39
45
import androidx.compose.material3.Text
40
46
import androidx.compose.material3.TopAppBarDefaults
41
47
import androidx.compose.runtime.Composable
42
48
import androidx.compose.runtime.collectAsState
43
49
import androidx.compose.runtime.getValue
44
- import androidx.compose.runtime.remember
45
50
import androidx.compose.ui.Alignment
46
51
import androidx.compose.ui.Modifier
52
+ import androidx.compose.ui.graphics.Color
47
53
import androidx.compose.ui.platform.LocalContext
48
54
import androidx.compose.ui.res.stringResource
55
+ import androidx.compose.ui.text.style.TextAlign
56
+ import androidx.compose.ui.tooling.preview.Preview
49
57
import androidx.compose.ui.unit.dp
50
58
import androidx.lifecycle.viewmodel.compose.viewModel
59
+ import com.example.fruitties.android.MyApplicationTheme
51
60
import com.example.fruitties.android.R
52
61
import com.example.fruitties.android.di.App
62
+ import com.example.fruitties.model.CartItemDetails
63
+ import com.example.fruitties.model.Fruittie
64
+ import com.example.fruitties.viewmodel.CartUiState
53
65
import com.example.fruitties.viewmodel.CartViewModel
66
+ import com.example.fruitties.viewmodel.creationExtras
54
67
55
- @OptIn(ExperimentalMaterial3Api ::class )
56
68
@Composable
57
69
fun CartScreen (onNavBarBack : () -> Unit ) {
58
70
// Instantiate a ViewModel with a dependency on the AppContainer.
@@ -61,17 +73,30 @@ fun CartScreen(onNavBarBack: () -> Unit) {
61
73
// Here we put the KMP-compatible AppContainer into the extras
62
74
// so it can be passed to the ViewModel factory.
63
75
val app = LocalContext .current.applicationContext as App
64
- val extras = remember(app) {
65
- val container = app.container
66
- CartViewModel .creationExtras(container)
67
- }
76
+
68
77
val viewModel: CartViewModel = viewModel(
69
78
factory = CartViewModel .Factory ,
70
- extras = extras ,
79
+ extras = creationExtras(app.container) ,
71
80
)
72
81
73
82
val cartState by viewModel.cartUiState.collectAsState()
74
83
84
+ CartScreen (
85
+ onNavBarBack = onNavBarBack,
86
+ cartState = cartState,
87
+ increaseCountClick = viewModel::increaseCountClick,
88
+ decreaseCountClick = viewModel::decreaseCountClick,
89
+ )
90
+ }
91
+
92
+ @OptIn(ExperimentalMaterial3Api ::class )
93
+ @Composable
94
+ fun CartScreen (
95
+ onNavBarBack : () -> Unit ,
96
+ cartState : CartUiState ,
97
+ decreaseCountClick : (CartItemDetails ) -> Unit ,
98
+ increaseCountClick : (CartItemDetails ) -> Unit ,
99
+ ) {
75
100
Scaffold (
76
101
topBar = {
77
102
CenterAlignedTopAppBar (
@@ -84,7 +109,7 @@ fun CartScreen(onNavBarBack: () -> Unit) {
84
109
}
85
110
},
86
111
title = {
87
- Text (text = stringResource(R .string.frutties ))
112
+ Text (text = stringResource(R .string.cart ))
88
113
},
89
114
colors = TopAppBarDefaults .topAppBarColors(
90
115
containerColor = MaterialTheme .colorScheme.primary,
@@ -103,22 +128,24 @@ fun CartScreen(onNavBarBack: () -> Unit) {
103
128
) { paddingValues ->
104
129
Column (
105
130
modifier = Modifier
106
- // Support edge-to-edge (required on Android 15)
107
- // https://developer.android.com/develop/ui/compose/layouts/insets#inset-size
108
131
.padding(paddingValues)
132
+ .consumeWindowInsets(paddingValues)
109
133
.padding(16 .dp),
110
134
) {
111
135
val cartItemCount = cartState.totalItemCount
112
136
Text (
113
- text = " Cart has $cartItemCount items" ,
114
- modifier = Modifier .padding(8 .dp),
137
+ text = stringResource(R .string.cart_has_items, cartItemCount),
115
138
)
139
+ HorizontalDivider ()
116
140
LazyColumn (
117
141
modifier = Modifier .fillMaxWidth(),
118
- horizontalAlignment = Alignment .CenterHorizontally ,
119
142
) {
120
143
items(cartState.cartDetails) { cartItem ->
121
- Text (text = " ${cartItem.fruittie.name} : ${cartItem.count} " )
144
+ CartItem (
145
+ cartItem = cartItem,
146
+ decreaseCountClick = decreaseCountClick,
147
+ increaseCountClick = increaseCountClick,
148
+ )
122
149
}
123
150
item {
124
151
Spacer (
@@ -131,3 +158,100 @@ fun CartScreen(onNavBarBack: () -> Unit) {
131
158
}
132
159
}
133
160
}
161
+
162
+ @Composable
163
+ fun CartItem (
164
+ cartItem : CartItemDetails ,
165
+ increaseCountClick : (CartItemDetails ) -> Unit ,
166
+ decreaseCountClick : (CartItemDetails ) -> Unit ,
167
+ modifier : Modifier = Modifier ,
168
+ ) {
169
+ Row (
170
+ modifier = modifier,
171
+ verticalAlignment = Alignment .CenterVertically ,
172
+ ) {
173
+ Text (text = " ${cartItem.count} x" )
174
+ Spacer (Modifier .width(8 .dp))
175
+ Text (text = cartItem.fruittie.name)
176
+ Spacer (Modifier .weight(1f ))
177
+ FilledIconButton (
178
+ onClick = { decreaseCountClick(cartItem) },
179
+ colors = IconButtonDefaults .filledIconButtonColors(containerColor = MaterialTheme .colorScheme.error),
180
+ ) {
181
+ Text (
182
+ text = " -" ,
183
+ color = MaterialTheme .colorScheme.onPrimary,
184
+ textAlign = TextAlign .Center ,
185
+ )
186
+ }
187
+ FilledIconButton (
188
+ onClick = { increaseCountClick(cartItem) },
189
+ colors = IconButtonDefaults .filledIconButtonColors(containerColor = Color .Green ),
190
+ ) {
191
+ Text (
192
+ text = " +" ,
193
+ color = MaterialTheme .colorScheme.onPrimary,
194
+ textAlign = TextAlign .Center ,
195
+ )
196
+ }
197
+ }
198
+ }
199
+
200
+ @Preview
201
+ @Composable
202
+ private fun CartScreenPreview () {
203
+ MyApplicationTheme {
204
+ CartScreen (
205
+ onNavBarBack = {},
206
+ cartState = CartUiState (
207
+ cartDetails = listOf (
208
+ CartItemDetails (
209
+ fruittie = Fruittie (
210
+ name = " Banana" ,
211
+ fullName = " Banana Banana" ,
212
+ calories = " 100" ,
213
+ ),
214
+ count = 4 ,
215
+ ),
216
+ CartItemDetails (
217
+ fruittie = Fruittie (
218
+ name = " Orange" ,
219
+ fullName = " Orange Orange" ,
220
+ calories = " 100" ,
221
+ ),
222
+ count = 1 ,
223
+ ),
224
+ CartItemDetails (
225
+ fruittie = Fruittie (
226
+ name = " Apple" ,
227
+ fullName = " Apple Apple" ,
228
+ calories = " 100" ,
229
+ ),
230
+ count = 100 ,
231
+ ),
232
+ ),
233
+ ),
234
+ decreaseCountClick = {},
235
+ increaseCountClick = {},
236
+ )
237
+ }
238
+ }
239
+
240
+ @Preview
241
+ @Composable
242
+ private fun CartItemPreview () {
243
+ MyApplicationTheme {
244
+ CartItem (
245
+ cartItem = CartItemDetails (
246
+ fruittie = Fruittie (
247
+ name = " Banana" ,
248
+ fullName = " Banana Banana" ,
249
+ calories = " 100" ,
250
+ ),
251
+ count = 4 ,
252
+ ),
253
+ increaseCountClick = {},
254
+ decreaseCountClick = {},
255
+ )
256
+ }
257
+ }
0 commit comments