Compare commits
	
		
			10 Commits
		
	
	
		
			066aa68e80
			...
			82b7dc7723
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					82b7dc7723 | ||
| 
						 | 
					8b50e72975 | ||
| 
						 | 
					7097a75f37 | ||
| 
						 | 
					a5118e6dfe | ||
| 
						 | 
					8f9aedaebc | ||
| 
						 | 
					5b8dab87ee | ||
| 
						 | 
					1c31d367a1 | ||
| 
						 | 
					14f13dd912 | ||
| 
						 | 
					94e3827d7c | ||
| 
						 | 
					fa202ff162 | 
							
								
								
									
										6
									
								
								.github/renovate.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.github/renovate.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
 | 
			
		||||
  "extends": [
 | 
			
		||||
    "local>android/.github:renovate-config"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@ -5,15 +5,12 @@ This app contains an order flow for cupcakes with options for quantity, flavor,
 | 
			
		||||
The order details get displayed on an order summary screen and can be shared to another app to
 | 
			
		||||
send the order.
 | 
			
		||||
 | 
			
		||||
TODO
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Pre-requisites
 | 
			
		||||
--------------
 | 
			
		||||
* Experience with Kotlin syntax.
 | 
			
		||||
* How to create and run a project in Android Studio.
 | 
			
		||||
* How to create composable functions 
 | 
			
		||||
* TODO
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Getting Started
 | 
			
		||||
 | 
			
		||||
@ -1,90 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2023 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
plugins {
 | 
			
		||||
    id 'com.android.application'
 | 
			
		||||
    id 'org.jetbrains.kotlin.android'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
android {
 | 
			
		||||
    namespace 'com.example.cupcake'
 | 
			
		||||
    compileSdk 33
 | 
			
		||||
 | 
			
		||||
    defaultConfig {
 | 
			
		||||
        applicationId "com.example.cupcake"
 | 
			
		||||
        minSdk 24
 | 
			
		||||
        targetSdk 33
 | 
			
		||||
        versionCode 1
 | 
			
		||||
        versionName "1.0"
 | 
			
		||||
 | 
			
		||||
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 | 
			
		||||
        vectorDrawables {
 | 
			
		||||
            useSupportLibrary true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildTypes {
 | 
			
		||||
        release {
 | 
			
		||||
            minifyEnabled false
 | 
			
		||||
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    compileOptions {
 | 
			
		||||
        sourceCompatibility JavaVersion.VERSION_1_8
 | 
			
		||||
        targetCompatibility JavaVersion.VERSION_1_8
 | 
			
		||||
    }
 | 
			
		||||
    kotlinOptions {
 | 
			
		||||
        jvmTarget = '1.8'
 | 
			
		||||
        freeCompilerArgs += "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api"
 | 
			
		||||
    }
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        compose true
 | 
			
		||||
    }
 | 
			
		||||
    composeOptions {
 | 
			
		||||
        kotlinCompilerExtensionVersion '1.4.7'
 | 
			
		||||
    }
 | 
			
		||||
    packagingOptions {
 | 
			
		||||
        resources {
 | 
			
		||||
            excludes += '/META-INF/{AL2.0,LGPL2.1}'
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
 | 
			
		||||
    implementation platform('androidx.compose:compose-bom:2023.05.00')
 | 
			
		||||
    implementation 'androidx.activity:activity-compose:1.7.1'
 | 
			
		||||
    implementation 'androidx.compose.material3:material3'
 | 
			
		||||
    implementation 'androidx.compose.runtime:runtime'
 | 
			
		||||
    implementation 'androidx.compose.runtime:runtime-livedata'
 | 
			
		||||
    implementation 'androidx.compose.ui:ui'
 | 
			
		||||
    implementation 'androidx.compose.ui:ui-graphics'
 | 
			
		||||
    implementation 'androidx.compose.ui:ui-tooling-preview'
 | 
			
		||||
    implementation 'androidx.core:core-ktx:1.10.0'
 | 
			
		||||
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
 | 
			
		||||
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
 | 
			
		||||
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
 | 
			
		||||
    implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
 | 
			
		||||
    implementation 'androidx.navigation:navigation-compose:2.5.3'
 | 
			
		||||
 | 
			
		||||
    androidTestImplementation platform('androidx.compose:compose-bom:2023.05.00')
 | 
			
		||||
    androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
 | 
			
		||||
    androidTestImplementation 'androidx.navigation:navigation-testing:2.5.3'
 | 
			
		||||
    androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1'
 | 
			
		||||
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
 | 
			
		||||
 | 
			
		||||
    debugImplementation 'androidx.compose.ui:ui-test-manifest'
 | 
			
		||||
    debugImplementation 'androidx.compose.ui:ui-tooling'
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										93
									
								
								app/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								app/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,93 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2023 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
plugins {
 | 
			
		||||
    id("com.android.application")
 | 
			
		||||
    id("org.jetbrains.kotlin.android")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
android {
 | 
			
		||||
    namespace = "com.example.cupcake"
 | 
			
		||||
    compileSdk = 34
 | 
			
		||||
 | 
			
		||||
    defaultConfig {
 | 
			
		||||
        applicationId = "com.example.cupcake"
 | 
			
		||||
        minSdk = 24
 | 
			
		||||
        targetSdk = 34
 | 
			
		||||
        versionCode = 1
 | 
			
		||||
        versionName = "1.0"
 | 
			
		||||
 | 
			
		||||
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
 | 
			
		||||
        vectorDrawables {
 | 
			
		||||
            useSupportLibrary = true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildTypes {
 | 
			
		||||
        release {
 | 
			
		||||
            isMinifyEnabled = false
 | 
			
		||||
            proguardFiles(
 | 
			
		||||
                getDefaultProguardFile("proguard-android-optimize.txt"),
 | 
			
		||||
                "proguard-rules.pro"
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    compileOptions {
 | 
			
		||||
        sourceCompatibility = JavaVersion.VERSION_1_8
 | 
			
		||||
        targetCompatibility = JavaVersion.VERSION_1_8
 | 
			
		||||
    }
 | 
			
		||||
    kotlinOptions {
 | 
			
		||||
        jvmTarget = "1.8"
 | 
			
		||||
        freeCompilerArgs += "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api"
 | 
			
		||||
    }
 | 
			
		||||
    buildFeatures {
 | 
			
		||||
        compose = true
 | 
			
		||||
    }
 | 
			
		||||
    composeOptions {
 | 
			
		||||
        kotlinCompilerExtensionVersion = "1.5.3"
 | 
			
		||||
    }
 | 
			
		||||
    packaging {
 | 
			
		||||
        resources {
 | 
			
		||||
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
 | 
			
		||||
    implementation(platform("androidx.compose:compose-bom:2023.10.01"))
 | 
			
		||||
    implementation("androidx.activity:activity-compose:1.8.0")
 | 
			
		||||
    implementation("androidx.compose.material3:material3")
 | 
			
		||||
    implementation("androidx.compose.runtime:runtime")
 | 
			
		||||
    implementation("androidx.compose.runtime:runtime-livedata")
 | 
			
		||||
    implementation("androidx.compose.ui:ui")
 | 
			
		||||
    implementation("androidx.compose.ui:ui-graphics")
 | 
			
		||||
    implementation("androidx.compose.ui:ui-tooling-preview")
 | 
			
		||||
    implementation("androidx.core:core-ktx:1.12.0")
 | 
			
		||||
    implementation("androidx.lifecycle:lifecycle-livedata-ktx:${rootProject.extra["lifecycle_version"]}")
 | 
			
		||||
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:${rootProject.extra["lifecycle_version"]}")
 | 
			
		||||
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:${rootProject.extra["lifecycle_version"]}")
 | 
			
		||||
    implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:${rootProject.extra["lifecycle_version"]}")
 | 
			
		||||
    implementation("androidx.navigation:navigation-compose:2.7.4")
 | 
			
		||||
 | 
			
		||||
    androidTestImplementation(platform("androidx.compose:compose-bom:2023.10.01"))
 | 
			
		||||
    androidTestImplementation("androidx.compose.ui:ui-test-junit4")
 | 
			
		||||
    androidTestImplementation("androidx.navigation:navigation-testing:2.7.4")
 | 
			
		||||
    androidTestImplementation("androidx.test.espresso:espresso-intents:3.5.1")
 | 
			
		||||
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
 | 
			
		||||
 | 
			
		||||
    debugImplementation("androidx.compose.ui:ui-test-manifest")
 | 
			
		||||
    debugImplementation("androidx.compose.ui:ui-tooling")
 | 
			
		||||
}
 | 
			
		||||
@ -76,25 +76,25 @@ class CupcakeOrderScreenTest {
 | 
			
		||||
    @Test
 | 
			
		||||
    fun selectOptionScreen_verifyContent() {
 | 
			
		||||
        // Given list of options
 | 
			
		||||
        val flavours = listOf("Vanilla", "Chocolate", "Hazelnut", "Cookie", "Mango")
 | 
			
		||||
        // And sub total
 | 
			
		||||
        val subTotal = "$100"
 | 
			
		||||
        val flavors = listOf("Vanilla", "Chocolate", "Hazelnut", "Cookie", "Mango")
 | 
			
		||||
        // And subtotal
 | 
			
		||||
        val subtotal = "$100"
 | 
			
		||||
 | 
			
		||||
        // When SelectOptionScreen is loaded
 | 
			
		||||
        composeTestRule.setContent {
 | 
			
		||||
            SelectOptionScreen(subtotal = subTotal, options = flavours)
 | 
			
		||||
            SelectOptionScreen(subtotal = subtotal, options = flavors)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Then all the options are displayed on the screen.
 | 
			
		||||
        flavours.forEach { flavour ->
 | 
			
		||||
            composeTestRule.onNodeWithText(flavour).assertIsDisplayed()
 | 
			
		||||
        flavors.forEach { flavor ->
 | 
			
		||||
            composeTestRule.onNodeWithText(flavor).assertIsDisplayed()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // And then the subtotal is displayed correctly.
 | 
			
		||||
        composeTestRule.onNodeWithText(
 | 
			
		||||
            composeTestRule.activity.getString(
 | 
			
		||||
                R.string.subtotal_price,
 | 
			
		||||
                subTotal
 | 
			
		||||
                subtotal
 | 
			
		||||
            )
 | 
			
		||||
        ).assertIsDisplayed()
 | 
			
		||||
 | 
			
		||||
@ -148,6 +148,6 @@ class CupcakeOrderScreenTest {
 | 
			
		||||
                R.string.subtotal_price,
 | 
			
		||||
                fakeOrderUiState.price
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        ).assertIsDisplayed()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,8 @@ import androidx.annotation.StringRes
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxHeight
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxSize
 | 
			
		||||
import androidx.compose.foundation.layout.padding
 | 
			
		||||
import androidx.compose.foundation.rememberScrollState
 | 
			
		||||
import androidx.compose.foundation.verticalScroll
 | 
			
		||||
import androidx.compose.material.icons.Icons
 | 
			
		||||
import androidx.compose.material.icons.filled.ArrowBack
 | 
			
		||||
import androidx.compose.material3.Icon
 | 
			
		||||
@ -115,7 +117,10 @@ fun CupcakeApp(
 | 
			
		||||
        NavHost(
 | 
			
		||||
            navController = navController,
 | 
			
		||||
            startDestination = CupcakeScreen.Start.name,
 | 
			
		||||
            modifier = Modifier.padding(innerPadding)
 | 
			
		||||
            modifier = Modifier
 | 
			
		||||
                .fillMaxSize()
 | 
			
		||||
                .verticalScroll(rememberScrollState())
 | 
			
		||||
                .padding(innerPadding)
 | 
			
		||||
        ) {
 | 
			
		||||
            composable(route = CupcakeScreen.Start.name) {
 | 
			
		||||
                StartOrderScreen(
 | 
			
		||||
 | 
			
		||||
@ -18,13 +18,13 @@ package com.example.cupcake
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import androidx.activity.ComponentActivity
 | 
			
		||||
import androidx.activity.compose.setContent
 | 
			
		||||
import androidx.core.view.WindowCompat
 | 
			
		||||
import androidx.activity.enableEdgeToEdge
 | 
			
		||||
import com.example.cupcake.ui.theme.CupcakeTheme
 | 
			
		||||
 | 
			
		||||
class MainActivity : ComponentActivity() {
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        enableEdgeToEdge()
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
        WindowCompat.setDecorFitsSystemWindows(window, false)
 | 
			
		||||
        setContent {
 | 
			
		||||
            CupcakeTheme {
 | 
			
		||||
                CupcakeApp()
 | 
			
		||||
 | 
			
		||||
@ -39,6 +39,7 @@ import androidx.compose.ui.res.stringResource
 | 
			
		||||
import androidx.compose.ui.tooling.preview.Preview
 | 
			
		||||
import com.example.cupcake.R
 | 
			
		||||
import com.example.cupcake.ui.components.FormattedPriceLabel
 | 
			
		||||
import com.example.cupcake.ui.theme.CupcakeTheme
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Composable that displays the list of items as [RadioButton] options,
 | 
			
		||||
@ -54,14 +55,14 @@ fun SelectOptionScreen(
 | 
			
		||||
    onCancelButtonClicked: () -> Unit = {},
 | 
			
		||||
    onNextButtonClicked: () -> Unit = {},
 | 
			
		||||
    modifier: Modifier = Modifier
 | 
			
		||||
){
 | 
			
		||||
) {
 | 
			
		||||
    var selectedValue by rememberSaveable { mutableStateOf("") }
 | 
			
		||||
 | 
			
		||||
    Column(
 | 
			
		||||
        modifier = modifier,
 | 
			
		||||
        verticalArrangement = Arrangement.SpaceBetween
 | 
			
		||||
    ) {
 | 
			
		||||
        Column(modifier = Modifier.padding(dimensionResource(R.dimen.padding_medium))){
 | 
			
		||||
        Column(modifier = Modifier.padding(dimensionResource(R.dimen.padding_medium))) {
 | 
			
		||||
            options.forEach { item ->
 | 
			
		||||
                Row(
 | 
			
		||||
                    modifier = Modifier.selectable(
 | 
			
		||||
@ -72,7 +73,7 @@ fun SelectOptionScreen(
 | 
			
		||||
                        }
 | 
			
		||||
                    ),
 | 
			
		||||
                    verticalAlignment = Alignment.CenterVertically
 | 
			
		||||
                ){
 | 
			
		||||
                ) {
 | 
			
		||||
                    RadioButton(
 | 
			
		||||
                        selected = selectedValue == item,
 | 
			
		||||
                        onClick = {
 | 
			
		||||
@ -100,12 +101,14 @@ fun SelectOptionScreen(
 | 
			
		||||
        Row(
 | 
			
		||||
            modifier = Modifier
 | 
			
		||||
                .fillMaxWidth()
 | 
			
		||||
                .padding(dimensionResource(R.dimen.padding_medium))
 | 
			
		||||
                .weight(1f, false),
 | 
			
		||||
                .padding(dimensionResource(R.dimen.padding_medium)),
 | 
			
		||||
            horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_medium)),
 | 
			
		||||
            verticalAlignment = Alignment.Bottom
 | 
			
		||||
        ){
 | 
			
		||||
            OutlinedButton(modifier = Modifier.weight(1f), onClick = onCancelButtonClicked) {
 | 
			
		||||
        ) {
 | 
			
		||||
            OutlinedButton(
 | 
			
		||||
                modifier = Modifier.weight(1f),
 | 
			
		||||
                onClick = onCancelButtonClicked
 | 
			
		||||
            ) {
 | 
			
		||||
                Text(stringResource(R.string.cancel))
 | 
			
		||||
            }
 | 
			
		||||
            Button(
 | 
			
		||||
@ -123,10 +126,12 @@ fun SelectOptionScreen(
 | 
			
		||||
 | 
			
		||||
@Preview
 | 
			
		||||
@Composable
 | 
			
		||||
fun SelectOptionPreview(){
 | 
			
		||||
    SelectOptionScreen(
 | 
			
		||||
        subtotal = "299.99",
 | 
			
		||||
        options = listOf("Option 1", "Option 2", "Option 3", "Option 4"),
 | 
			
		||||
        modifier = Modifier.fillMaxHeight()
 | 
			
		||||
    )
 | 
			
		||||
fun SelectOptionPreview() {
 | 
			
		||||
    CupcakeTheme {
 | 
			
		||||
        SelectOptionScreen(
 | 
			
		||||
            subtotal = "299.99",
 | 
			
		||||
            options = listOf("Option 1", "Option 2", "Option 3", "Option 4"),
 | 
			
		||||
            modifier = Modifier.fillMaxHeight()
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -19,9 +19,7 @@ import androidx.annotation.StringRes
 | 
			
		||||
import androidx.compose.foundation.Image
 | 
			
		||||
import androidx.compose.foundation.layout.Arrangement
 | 
			
		||||
import androidx.compose.foundation.layout.Column
 | 
			
		||||
import androidx.compose.foundation.layout.Row
 | 
			
		||||
import androidx.compose.foundation.layout.Spacer
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxHeight
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxSize
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxWidth
 | 
			
		||||
import androidx.compose.foundation.layout.height
 | 
			
		||||
@ -41,6 +39,7 @@ import androidx.compose.ui.tooling.preview.Preview
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import com.example.cupcake.R
 | 
			
		||||
import com.example.cupcake.data.DataSource
 | 
			
		||||
import com.example.cupcake.ui.theme.CupcakeTheme
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Composable that allows the user to select the desired cupcake quantity and expects
 | 
			
		||||
@ -52,7 +51,7 @@ fun StartOrderScreen(
 | 
			
		||||
    quantityOptions: List<Pair<Int, Int>>,
 | 
			
		||||
    onNextButtonClicked: (Int) -> Unit,
 | 
			
		||||
    modifier: Modifier = Modifier
 | 
			
		||||
){
 | 
			
		||||
) {
 | 
			
		||||
    Column(
 | 
			
		||||
        modifier = modifier,
 | 
			
		||||
        verticalArrangement = Arrangement.SpaceBetween
 | 
			
		||||
@ -75,20 +74,19 @@ fun StartOrderScreen(
 | 
			
		||||
            )
 | 
			
		||||
            Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
 | 
			
		||||
        }
 | 
			
		||||
        Row(modifier = Modifier.weight(1f, false)) {
 | 
			
		||||
            Column(
 | 
			
		||||
                modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                horizontalAlignment = Alignment.CenterHorizontally,
 | 
			
		||||
                verticalArrangement = Arrangement.spacedBy(
 | 
			
		||||
                    dimensionResource(id = R.dimen.padding_medium)
 | 
			
		||||
        Column(
 | 
			
		||||
            modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
            horizontalAlignment = Alignment.CenterHorizontally,
 | 
			
		||||
            verticalArrangement = Arrangement.spacedBy(
 | 
			
		||||
                dimensionResource(id = R.dimen.padding_medium)
 | 
			
		||||
            )
 | 
			
		||||
        ) {
 | 
			
		||||
            quantityOptions.forEach { item ->
 | 
			
		||||
                SelectQuantityButton(
 | 
			
		||||
                    labelResourceId = item.first,
 | 
			
		||||
                    onClick = { onNextButtonClicked(item.second) },
 | 
			
		||||
                    modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                )
 | 
			
		||||
            ) {
 | 
			
		||||
                quantityOptions.forEach { item ->
 | 
			
		||||
                    SelectQuantityButton(
 | 
			
		||||
                        labelResourceId = item.first,
 | 
			
		||||
                        onClick = { onNextButtonClicked(item.second) }
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -103,7 +101,7 @@ fun SelectQuantityButton(
 | 
			
		||||
    @StringRes labelResourceId: Int,
 | 
			
		||||
    onClick: () -> Unit,
 | 
			
		||||
    modifier: Modifier = Modifier
 | 
			
		||||
){
 | 
			
		||||
) {
 | 
			
		||||
    Button(
 | 
			
		||||
        onClick = onClick,
 | 
			
		||||
        modifier = modifier.widthIn(min = 250.dp)
 | 
			
		||||
@ -114,10 +112,14 @@ fun SelectQuantityButton(
 | 
			
		||||
 | 
			
		||||
@Preview
 | 
			
		||||
@Composable
 | 
			
		||||
fun StartOrderPreview(){
 | 
			
		||||
    StartOrderScreen(
 | 
			
		||||
        quantityOptions = DataSource.quantityOptions,
 | 
			
		||||
        onNextButtonClicked = {},
 | 
			
		||||
        modifier = Modifier.fillMaxSize().padding(dimensionResource(R.dimen.padding_medium))
 | 
			
		||||
    )
 | 
			
		||||
fun StartOrderPreview() {
 | 
			
		||||
    CupcakeTheme {
 | 
			
		||||
        StartOrderScreen(
 | 
			
		||||
            quantityOptions = DataSource.quantityOptions,
 | 
			
		||||
            onNextButtonClicked = {},
 | 
			
		||||
            modifier = Modifier
 | 
			
		||||
                .fillMaxSize()
 | 
			
		||||
                .padding(dimensionResource(R.dimen.padding_medium))
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,7 @@ import androidx.compose.ui.tooling.preview.Preview
 | 
			
		||||
import com.example.cupcake.R
 | 
			
		||||
import com.example.cupcake.data.OrderUiState
 | 
			
		||||
import com.example.cupcake.ui.components.FormattedPriceLabel
 | 
			
		||||
import com.example.cupcake.ui.theme.CupcakeTheme
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This composable expects [orderUiState] that represents the order state, [onCancelButtonClicked]
 | 
			
		||||
@ -50,7 +51,7 @@ fun OrderSummaryScreen(
 | 
			
		||||
    onCancelButtonClicked: () -> Unit,
 | 
			
		||||
    onSendButtonClicked: (String, String) -> Unit,
 | 
			
		||||
    modifier: Modifier = Modifier
 | 
			
		||||
){
 | 
			
		||||
) {
 | 
			
		||||
    val resources = LocalContext.current.resources
 | 
			
		||||
 | 
			
		||||
    val numberOfCupcakes = resources.getQuantityString(
 | 
			
		||||
@ -97,9 +98,7 @@ fun OrderSummaryScreen(
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        Row(
 | 
			
		||||
            modifier = Modifier
 | 
			
		||||
                .weight(1f, false)
 | 
			
		||||
                .padding(dimensionResource(R.dimen.padding_medium))
 | 
			
		||||
            modifier = Modifier.padding(dimensionResource(R.dimen.padding_medium))
 | 
			
		||||
        ) {
 | 
			
		||||
            Column(
 | 
			
		||||
                verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_small))
 | 
			
		||||
@ -123,11 +122,13 @@ fun OrderSummaryScreen(
 | 
			
		||||
 | 
			
		||||
@Preview
 | 
			
		||||
@Composable
 | 
			
		||||
fun OrderSummaryPreview(){
 | 
			
		||||
    OrderSummaryScreen(
 | 
			
		||||
        orderUiState = OrderUiState(0, "Test", "Test", "$300.00"),
 | 
			
		||||
        onSendButtonClicked = { subject: String, summary: String -> },
 | 
			
		||||
        onCancelButtonClicked = {},
 | 
			
		||||
        modifier = Modifier.fillMaxHeight()
 | 
			
		||||
    )
 | 
			
		||||
fun OrderSummaryPreview() {
 | 
			
		||||
    CupcakeTheme {
 | 
			
		||||
        OrderSummaryScreen(
 | 
			
		||||
            orderUiState = OrderUiState(0, "Test", "Test", "$300.00"),
 | 
			
		||||
            onSendButtonClicked = { subject: String, summary: String -> },
 | 
			
		||||
            onCancelButtonClicked = {},
 | 
			
		||||
            modifier = Modifier.fillMaxHeight()
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,4 +32,4 @@ fun FormattedPriceLabel(subtotal: String, modifier: Modifier = Modifier) {
 | 
			
		||||
        modifier = modifier,
 | 
			
		||||
        style = MaterialTheme.typography.headlineSmall
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -15,12 +15,12 @@
 | 
			
		||||
 */
 | 
			
		||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
 | 
			
		||||
buildscript {
 | 
			
		||||
    ext {
 | 
			
		||||
        lifecycle_version = "2.6.1"
 | 
			
		||||
    extra.apply {
 | 
			
		||||
        set("lifecycle_version", "2.6.2")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
plugins {
 | 
			
		||||
    id 'com.android.application' version '8.0.1' apply false
 | 
			
		||||
    id 'com.android.library' version '8.0.1' apply false
 | 
			
		||||
    id 'org.jetbrains.kotlin.android' version '1.8.21' apply false
 | 
			
		||||
    id("com.android.application") version "8.1.2" apply false
 | 
			
		||||
    id("com.android.library") version "8.1.2" apply false
 | 
			
		||||
    id("org.jetbrains.kotlin.android") version "1.9.10" apply false
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							@ -1,6 +1,6 @@
 | 
			
		||||
#Sun Mar 19 17:30:22 PDT 2023
 | 
			
		||||
distributionBase=GRADLE_USER_HOME
 | 
			
		||||
distributionPath=wrapper/dists
 | 
			
		||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
 | 
			
		||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
 | 
			
		||||
zipStoreBase=GRADLE_USER_HOME
 | 
			
		||||
zipStorePath=wrapper/dists
 | 
			
		||||
 | 
			
		||||
@ -28,4 +28,4 @@ dependencyResolutionManagement {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
rootProject.name = "Cupcake"
 | 
			
		||||
include ':app'
 | 
			
		||||
include(":app")
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user