1717package com.example.fruitties.android.ui
1818
1919import androidx.compose.foundation.layout.Column
20+ import androidx.compose.foundation.layout.Row
2021import androidx.compose.foundation.layout.Spacer
2122import androidx.compose.foundation.layout.WindowInsets
2223import androidx.compose.foundation.layout.WindowInsetsSides
24+ import androidx.compose.foundation.layout.consumeWindowInsets
2325import androidx.compose.foundation.layout.fillMaxWidth
2426import androidx.compose.foundation.layout.only
2527import androidx.compose.foundation.layout.padding
2628import androidx.compose.foundation.layout.safeDrawing
2729import androidx.compose.foundation.layout.systemBars
30+ import androidx.compose.foundation.layout.width
2831import androidx.compose.foundation.layout.windowInsetsBottomHeight
2932import androidx.compose.foundation.lazy.LazyColumn
3033import androidx.compose.foundation.lazy.items
3134import androidx.compose.material.icons.Icons
3235import androidx.compose.material.icons.automirrored.filled.ArrowBack
3336import androidx.compose.material3.CenterAlignedTopAppBar
3437import androidx.compose.material3.ExperimentalMaterial3Api
38+ import androidx.compose.material3.FilledIconButton
39+ import androidx.compose.material3.HorizontalDivider
3540import androidx.compose.material3.Icon
3641import androidx.compose.material3.IconButton
42+ import androidx.compose.material3.IconButtonDefaults
3743import androidx.compose.material3.MaterialTheme
3844import androidx.compose.material3.Scaffold
3945import androidx.compose.material3.Text
4046import androidx.compose.material3.TopAppBarDefaults
4147import androidx.compose.runtime.Composable
4248import androidx.compose.runtime.collectAsState
4349import androidx.compose.runtime.getValue
44- import androidx.compose.runtime.remember
4550import androidx.compose.ui.Alignment
4651import androidx.compose.ui.Modifier
52+ import androidx.compose.ui.graphics.Color
4753import androidx.compose.ui.platform.LocalContext
4854import androidx.compose.ui.res.stringResource
55+ import androidx.compose.ui.text.style.TextAlign
56+ import androidx.compose.ui.tooling.preview.Preview
4957import androidx.compose.ui.unit.dp
5058import androidx.lifecycle.viewmodel.compose.viewModel
59+ import com.example.fruitties.android.MyApplicationTheme
5160import com.example.fruitties.android.R
5261import 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
5365import com.example.fruitties.viewmodel.CartViewModel
66+ import com.example.fruitties.viewmodel.creationExtras
5467
55- @OptIn(ExperimentalMaterial3Api ::class )
5668@Composable
5769fun CartScreen (onNavBarBack : () -> Unit ) {
5870 // Instantiate a ViewModel with a dependency on the AppContainer.
@@ -61,17 +73,30 @@ fun CartScreen(onNavBarBack: () -> Unit) {
6173 // Here we put the KMP-compatible AppContainer into the extras
6274 // so it can be passed to the ViewModel factory.
6375 val app = LocalContext .current.applicationContext as App
64- val extras = remember(app) {
65- val container = app.container
66- CartViewModel .creationExtras(container)
67- }
76+
6877 val viewModel: CartViewModel = viewModel(
6978 factory = CartViewModel .Factory ,
70- extras = extras ,
79+ extras = creationExtras(app.container) ,
7180 )
7281
7382 val cartState by viewModel.cartUiState.collectAsState()
7483
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+ ) {
75100 Scaffold (
76101 topBar = {
77102 CenterAlignedTopAppBar (
@@ -84,7 +109,7 @@ fun CartScreen(onNavBarBack: () -> Unit) {
84109 }
85110 },
86111 title = {
87- Text (text = stringResource(R .string.frutties ))
112+ Text (text = stringResource(R .string.cart ))
88113 },
89114 colors = TopAppBarDefaults .topAppBarColors(
90115 containerColor = MaterialTheme .colorScheme.primary,
@@ -103,22 +128,24 @@ fun CartScreen(onNavBarBack: () -> Unit) {
103128 ) { paddingValues ->
104129 Column (
105130 modifier = Modifier
106- // Support edge-to-edge (required on Android 15)
107- // https://developer.android.com/develop/ui/compose/layouts/insets#inset-size
108131 .padding(paddingValues)
132+ .consumeWindowInsets(paddingValues)
109133 .padding(16 .dp),
110134 ) {
111135 val cartItemCount = cartState.totalItemCount
112136 Text (
113- text = " Cart has $cartItemCount items" ,
114- modifier = Modifier .padding(8 .dp),
137+ text = stringResource(R .string.cart_has_items, cartItemCount),
115138 )
139+ HorizontalDivider ()
116140 LazyColumn (
117141 modifier = Modifier .fillMaxWidth(),
118- horizontalAlignment = Alignment .CenterHorizontally ,
119142 ) {
120143 items(cartState.cartDetails) { cartItem ->
121- Text (text = " ${cartItem.fruittie.name} : ${cartItem.count} " )
144+ CartItem (
145+ cartItem = cartItem,
146+ decreaseCountClick = decreaseCountClick,
147+ increaseCountClick = increaseCountClick,
148+ )
122149 }
123150 item {
124151 Spacer (
@@ -131,3 +158,100 @@ fun CartScreen(onNavBarBack: () -> Unit) {
131158 }
132159 }
133160}
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