Commit a0fdee66c47822b560761d176324b4afc3548580

Authored by Luciana Fratean
0 parents

Initial commit with all project files#

Showing 77 changed files with 2928 additions and 0 deletions
  1 +*.iml
  2 +.gradle
  3 +/local.properties
  4 +/.idea/caches
  5 +/.idea/libraries
  6 +/.idea/modules.xml
  7 +/.idea/workspace.xml
  8 +/.idea/navEditor.xml
  9 +/.idea/assetWizardSettings.xml
  10 +.DS_Store
  11 +/build
  12 +/captures
  13 +.externalNativeBuild
  14 +.cxx
  15 +local.properties
  1 +# Default ignored files
  2 +/shelf/
  3 +/workspace.xml
  1 +CupcakeOrder
  1 +<component name="ProjectCodeStyleConfiguration">
  2 + <code_scheme name="Project" version="173">
  3 + <JetCodeStyleSettings>
  4 + <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
  5 + </JetCodeStyleSettings>
  6 + <codeStyleSettings language="XML">
  7 + <option name="FORCE_REARRANGE_MODE" value="1" />
  8 + <indentOptions>
  9 + <option name="CONTINUATION_INDENT_SIZE" value="4" />
  10 + </indentOptions>
  11 + <arrangement>
  12 + <rules>
  13 + <section>
  14 + <rule>
  15 + <match>
  16 + <AND>
  17 + <NAME>xmlns:android</NAME>
  18 + <XML_ATTRIBUTE />
  19 + <XML_NAMESPACE>^$</XML_NAMESPACE>
  20 + </AND>
  21 + </match>
  22 + </rule>
  23 + </section>
  24 + <section>
  25 + <rule>
  26 + <match>
  27 + <AND>
  28 + <NAME>xmlns:.*</NAME>
  29 + <XML_ATTRIBUTE />
  30 + <XML_NAMESPACE>^$</XML_NAMESPACE>
  31 + </AND>
  32 + </match>
  33 + <order>BY_NAME</order>
  34 + </rule>
  35 + </section>
  36 + <section>
  37 + <rule>
  38 + <match>
  39 + <AND>
  40 + <NAME>.*:id</NAME>
  41 + <XML_ATTRIBUTE />
  42 + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
  43 + </AND>
  44 + </match>
  45 + </rule>
  46 + </section>
  47 + <section>
  48 + <rule>
  49 + <match>
  50 + <AND>
  51 + <NAME>.*:name</NAME>
  52 + <XML_ATTRIBUTE />
  53 + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
  54 + </AND>
  55 + </match>
  56 + </rule>
  57 + </section>
  58 + <section>
  59 + <rule>
  60 + <match>
  61 + <AND>
  62 + <NAME>name</NAME>
  63 + <XML_ATTRIBUTE />
  64 + <XML_NAMESPACE>^$</XML_NAMESPACE>
  65 + </AND>
  66 + </match>
  67 + </rule>
  68 + </section>
  69 + <section>
  70 + <rule>
  71 + <match>
  72 + <AND>
  73 + <NAME>style</NAME>
  74 + <XML_ATTRIBUTE />
  75 + <XML_NAMESPACE>^$</XML_NAMESPACE>
  76 + </AND>
  77 + </match>
  78 + </rule>
  79 + </section>
  80 + <section>
  81 + <rule>
  82 + <match>
  83 + <AND>
  84 + <NAME>.*</NAME>
  85 + <XML_ATTRIBUTE />
  86 + <XML_NAMESPACE>^$</XML_NAMESPACE>
  87 + </AND>
  88 + </match>
  89 + <order>BY_NAME</order>
  90 + </rule>
  91 + </section>
  92 + <section>
  93 + <rule>
  94 + <match>
  95 + <AND>
  96 + <NAME>.*</NAME>
  97 + <XML_ATTRIBUTE />
  98 + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
  99 + </AND>
  100 + </match>
  101 + <order>ANDROID_ATTRIBUTE_ORDER</order>
  102 + </rule>
  103 + </section>
  104 + <section>
  105 + <rule>
  106 + <match>
  107 + <AND>
  108 + <NAME>.*</NAME>
  109 + <XML_ATTRIBUTE />
  110 + <XML_NAMESPACE>.*</XML_NAMESPACE>
  111 + </AND>
  112 + </match>
  113 + <order>BY_NAME</order>
  114 + </rule>
  115 + </section>
  116 + </rules>
  117 + </arrangement>
  118 + </codeStyleSettings>
  119 + <codeStyleSettings language="kotlin">
  120 + <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
  121 + </codeStyleSettings>
  122 + </code_scheme>
  123 +</component>
  1 +<component name="ProjectCodeStyleConfiguration">
  2 + <state>
  3 + <option name="USE_PER_PROJECT_SETTINGS" value="true" />
  4 + </state>
  5 +</component>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="CompilerConfiguration">
  4 + <bytecodeTargetLevel target="21" />
  5 + </component>
  6 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="deploymentTargetSelector">
  4 + <selectionStates>
  5 + <SelectionState runConfigName="app">
  6 + <option name="selectionMode" value="DROPDOWN" />
  7 + <DropdownSelection timestamp="2025-02-03T19:31:41.692201600Z">
  8 + <Target type="DEFAULT_BOOT">
  9 + <handle>
  10 + <DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Paul\.android\avd\Medium_Phone_API_35_2.avd" />
  11 + </handle>
  12 + </Target>
  13 + </DropdownSelection>
  14 + <DialogSelection />
  15 + </SelectionState>
  16 + </selectionStates>
  17 + </component>
  18 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="GradleMigrationSettings" migrationVersion="1" />
  4 + <component name="GradleSettings">
  5 + <option name="linkedExternalProjectsSettings">
  6 + <GradleProjectSettings>
  7 + <option name="testRunner" value="CHOOSE_PER_TEST" />
  8 + <option name="externalProjectPath" value="$PROJECT_DIR$" />
  9 + <option name="gradleJvm" value="jbr-21" />
  10 + <option name="modules">
  11 + <set>
  12 + <option value="$PROJECT_DIR$" />
  13 + <option value="$PROJECT_DIR$/app" />
  14 + </set>
  15 + </option>
  16 + <option name="resolveExternalAnnotations" value="false" />
  17 + </GradleProjectSettings>
  18 + </option>
  19 + </component>
  20 +</project>
  1 +<component name="InspectionProjectProfileManager">
  2 + <profile version="1.0">
  3 + <option name="myName" value="Project Default" />
  4 + <inspection_tool class="ComposePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
  5 + <option name="composableFile" value="true" />
  6 + <option name="previewFile" value="true" />
  7 + </inspection_tool>
  8 + <inspection_tool class="ComposePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
  9 + <option name="composableFile" value="true" />
  10 + <option name="previewFile" value="true" />
  11 + </inspection_tool>
  12 + <inspection_tool class="ComposePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
  13 + <option name="composableFile" value="true" />
  14 + <option name="previewFile" value="true" />
  15 + </inspection_tool>
  16 + <inspection_tool class="ComposePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
  17 + <option name="composableFile" value="true" />
  18 + <option name="previewFile" value="true" />
  19 + </inspection_tool>
  20 + <inspection_tool class="GlancePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
  21 + <option name="composableFile" value="true" />
  22 + </inspection_tool>
  23 + <inspection_tool class="GlancePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
  24 + <option name="composableFile" value="true" />
  25 + </inspection_tool>
  26 + <inspection_tool class="GlancePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
  27 + <option name="composableFile" value="true" />
  28 + </inspection_tool>
  29 + <inspection_tool class="GlancePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
  30 + <option name="composableFile" value="true" />
  31 + </inspection_tool>
  32 + <inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
  33 + <option name="composableFile" value="true" />
  34 + <option name="previewFile" value="true" />
  35 + </inspection_tool>
  36 + <inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
  37 + <option name="composableFile" value="true" />
  38 + <option name="previewFile" value="true" />
  39 + </inspection_tool>
  40 + <inspection_tool class="PreviewDeviceShouldUseNewSpec" enabled="true" level="WEAK WARNING" enabled_by_default="true">
  41 + <option name="composableFile" value="true" />
  42 + <option name="previewFile" value="true" />
  43 + </inspection_tool>
  44 + <inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
  45 + <option name="composableFile" value="true" />
  46 + <option name="previewFile" value="true" />
  47 + </inspection_tool>
  48 + <inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
  49 + <option name="composableFile" value="true" />
  50 + <option name="previewFile" value="true" />
  51 + </inspection_tool>
  52 + <inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
  53 + <option name="composableFile" value="true" />
  54 + <option name="previewFile" value="true" />
  55 + </inspection_tool>
  56 + </profile>
  57 +</component>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="KotlinJpsPluginSettings">
  4 + <option name="version" value="2.0.0" />
  5 + </component>
  6 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="ProjectMigrations">
  4 + <option name="MigrateToGradleLocalJavaHome">
  5 + <set>
  6 + <option value="$PROJECT_DIR$" />
  7 + </set>
  8 + </option>
  9 + </component>
  10 +</project>
  1 +<project version="4">
  2 + <component name="ExternalStorageConfigurationManager" enabled="true" />
  3 + <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
  4 + <output url="file://$PROJECT_DIR$/build/classes" />
  5 + </component>
  6 + <component name="ProjectType">
  7 + <option name="id" value="Android" />
  8 + </component>
  9 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="RunConfigurationProducerService">
  4 + <option name="ignoredProducers">
  5 + <set>
  6 + <option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
  7 + <option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
  8 + <option value="com.intellij.execution.junit.PatternConfigurationProducer" />
  9 + <option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
  10 + <option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
  11 + <option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
  12 + <option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
  13 + <option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
  14 + </set>
  15 + </option>
  16 + </component>
  17 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="VcsDirectoryMappings">
  4 + <mapping directory="$PROJECT_DIR$" vcs="Git" />
  5 + </component>
  6 +</project>
  1 +/build
  1 +plugins {
  2 + alias(libs.plugins.android.application)
  3 + alias(libs.plugins.kotlin.android)
  4 + alias(libs.plugins.kotlin.compose)
  5 + id("com.google.gms.google-services")
  6 +}
  7 +
  8 +android {
  9 + namespace = "com.example.pizzaorder"
  10 + compileSdk = 35
  11 +
  12 + defaultConfig {
  13 + applicationId = "com.example.pizzaorder"
  14 + minSdk = 24
  15 + targetSdk = 35
  16 + versionCode = 1
  17 + versionName = "1.0"
  18 +
  19 + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
  20 + }
  21 +
  22 + buildTypes {
  23 + release {
  24 + isMinifyEnabled = false
  25 + proguardFiles(
  26 + getDefaultProguardFile("proguard-android-optimize.txt"),
  27 + "proguard-rules.pro"
  28 + )
  29 + }
  30 + }
  31 + compileOptions {
  32 + sourceCompatibility = JavaVersion.VERSION_11
  33 + targetCompatibility = JavaVersion.VERSION_11
  34 + }
  35 + kotlinOptions {
  36 + jvmTarget = "11"
  37 + }
  38 + buildFeatures {
  39 + compose = true
  40 + }
  41 +}
  42 +
  43 +dependencies {
  44 +
  45 + implementation(libs.androidx.core.ktx)
  46 + implementation(libs.androidx.lifecycle.runtime.ktx)
  47 + implementation(libs.androidx.activity.compose)
  48 + implementation(platform(libs.androidx.compose.bom))
  49 + implementation(libs.androidx.ui)
  50 + implementation(libs.androidx.ui.graphics)
  51 + implementation(libs.androidx.ui.tooling.preview)
  52 + implementation(libs.androidx.material3)
  53 + implementation(libs.androidx.navigation.runtime.ktx)
  54 + implementation(libs.androidx.navigation.compose)
  55 + testImplementation(libs.junit)
  56 + androidTestImplementation(libs.androidx.junit)
  57 + androidTestImplementation(libs.androidx.espresso.core)
  58 + androidTestImplementation(platform(libs.androidx.compose.bom))
  59 + androidTestImplementation(libs.androidx.ui.test.junit4)
  60 + debugImplementation(libs.androidx.ui.tooling)
  61 + debugImplementation(libs.androidx.ui.test.manifest)
  62 + // Import the Firebase BoM
  63 + implementation(platform("com.google.firebase:firebase-bom:33.8.0"))
  64 +
  65 + // TODO: Add the dependencies for Firebase products you want to use
  66 + // When using the BoM, don't specify versions in Firebase dependencies
  67 + implementation("com.google.firebase:firebase-analytics")
  68 +
  69 + // Add the dependencies for any other desired Firebase products
  70 + // https://firebase.google.com/docs/android/setup#available-libraries
  71 + implementation("com.google.firebase:firebase-auth")
  72 + implementation("com.google.firebase:firebase-firestore")
  73 +
  74 +}
  1 +{
  2 + "project_info": {
  3 + "project_number": "322090362921",
  4 + "project_id": "cupcakeorder-40545",
  5 + "storage_bucket": "cupcakeorder-40545.firebasestorage.app"
  6 + },
  7 + "client": [
  8 + {
  9 + "client_info": {
  10 + "mobilesdk_app_id": "1:322090362921:android:bfcf253213b3fbd2069438",
  11 + "android_client_info": {
  12 + "package_name": "com.example.pizzaorder"
  13 + }
  14 + },
  15 + "oauth_client": [
  16 + {
  17 + "client_id": "322090362921-4m16acpm3qa3a3f5c8fbdrraioo45k21.apps.googleusercontent.com",
  18 + "client_type": 3
  19 + }
  20 + ],
  21 + "api_key": [
  22 + {
  23 + "current_key": "AIzaSyA_WB-ldFu9LuDcdcxZRVwVUv4KQpF4TKc"
  24 + }
  25 + ],
  26 + "services": {
  27 + "appinvite_service": {
  28 + "other_platform_oauth_client": [
  29 + {
  30 + "client_id": "322090362921-4m16acpm3qa3a3f5c8fbdrraioo45k21.apps.googleusercontent.com",
  31 + "client_type": 3
  32 + }
  33 + ]
  34 + }
  35 + }
  36 + }
  37 + ],
  38 + "configuration_version": "1"
  39 +}
  1 +# Add project specific ProGuard rules here.
  2 +# You can control the set of applied configuration files using the
  3 +# proguardFiles setting in build.gradle.
  4 +#
  5 +# For more details, see
  6 +# http://developer.android.com/guide/developing/tools/proguard.html
  7 +
  8 +# If your project uses WebView with JS, uncomment the following
  9 +# and specify the fully qualified class name to the JavaScript interface
  10 +# class:
  11 +#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
  12 +# public *;
  13 +#}
  14 +
  15 +# Uncomment this to preserve the line number information for
  16 +# debugging stack traces.
  17 +#-keepattributes SourceFile,LineNumberTable
  18 +
  19 +# If you keep the line number information, uncomment this to
  20 +# hide the original source file name.
  21 +#-renamesourcefileattribute SourceFile
  1 +package com.example.pizzaorder
  2 +
  3 +import androidx.test.platform.app.InstrumentationRegistry
  4 +import androidx.test.ext.junit.runners.AndroidJUnit4
  5 +
  6 +import org.junit.Test
  7 +import org.junit.runner.RunWith
  8 +
  9 +import org.junit.Assert.*
  10 +
  11 +
  12 +@RunWith(AndroidJUnit4::class)
  13 +class ExampleInstrumentedTest {
  14 + @Test
  15 + fun useAppContext() {
  16 + // Context of the app under test.
  17 + val appContext = InstrumentationRegistry.getInstrumentation().targetContext
  18 + assertEquals("com.example.pizzaorder", appContext.packageName)
  19 + }
  20 +}
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:tools="http://schemas.android.com/tools">
  4 +
  5 + <application
  6 + android:allowBackup="true"
  7 + android:dataExtractionRules="@xml/data_extraction_rules"
  8 + android:fullBackupContent="@xml/backup_rules"
  9 + android:icon="@mipmap/ic_launcher"
  10 + android:label="@string/app_name"
  11 + android:roundIcon="@mipmap/ic_launcher_round"
  12 + android:supportsRtl="true"
  13 + android:theme="@style/Theme.PizzaOrder"
  14 + tools:targetApi="31">
  15 + <activity
  16 + android:name=".MainActivity"
  17 + android:exported="true"
  18 + android:label="@string/app_name"
  19 + android:theme="@style/Theme.PizzaOrder">
  20 + <intent-filter>
  21 + <action android:name="android.intent.action.MAIN" />
  22 +
  23 + <category android:name="android.intent.category.LAUNCHER" />
  24 + </intent-filter>
  25 + </activity>
  26 + </application>
  27 +
  28 +</manifest>
  1 +package com.example.pizzaorder
  2 +
  3 +import android.os.Bundle
  4 +import androidx.activity.ComponentActivity
  5 +import androidx.activity.compose.setContent
  6 +import androidx.activity.enableEdgeToEdge
  7 +import com.example.pizzaorder.ui.theme.PizzaTheme
  8 +import com.google.firebase.FirebaseApp
  9 +
  10 +class MainActivity : ComponentActivity() {
  11 + override fun onCreate(savedInstanceState: Bundle?) {
  12 + enableEdgeToEdge()
  13 + super.onCreate(savedInstanceState)
  14 + FirebaseApp.initializeApp(this)
  15 + setContent {
  16 + PizzaTheme {
  17 + PizzaApp()
  18 + }
  19 + }
  20 + }
  21 +}
  1 +package com.example.pizzaorder
  2 +
  3 +import android.content.Context
  4 +import android.content.Intent
  5 +import androidx.annotation.StringRes
  6 +import androidx.compose.foundation.layout.Arrangement
  7 +import androidx.compose.foundation.layout.Column
  8 +import androidx.compose.foundation.layout.fillMaxSize
  9 +import androidx.compose.foundation.layout.fillMaxWidth
  10 +import androidx.compose.foundation.layout.padding
  11 +import androidx.compose.material.icons.Icons
  12 +import androidx.compose.material.icons.automirrored.filled.ArrowBack
  13 +import androidx.compose.material.icons.filled.MoreVert
  14 +import androidx.compose.material3.AlertDialog
  15 +import androidx.compose.material3.Button
  16 +import androidx.compose.material3.ButtonDefaults
  17 +import androidx.compose.material3.ExperimentalMaterial3Api
  18 +import androidx.compose.material3.HorizontalDivider
  19 +import androidx.compose.material3.Icon
  20 +import androidx.compose.material3.IconButton
  21 +import androidx.compose.material3.MaterialTheme
  22 +import androidx.compose.material3.ModalBottomSheet
  23 +import androidx.compose.material3.Scaffold
  24 +import androidx.compose.material3.Text
  25 +import androidx.compose.material3.TopAppBar
  26 +import androidx.compose.material3.TopAppBarDefaults
  27 +import androidx.compose.material3.rememberModalBottomSheetState
  28 +import androidx.compose.runtime.Composable
  29 +import androidx.compose.runtime.collectAsState
  30 +import androidx.compose.runtime.getValue
  31 +import androidx.compose.runtime.mutableStateOf
  32 +import androidx.compose.runtime.remember
  33 +import androidx.compose.runtime.rememberCoroutineScope
  34 +import androidx.compose.runtime.setValue
  35 +import androidx.compose.ui.Modifier
  36 +import androidx.compose.ui.graphics.Color
  37 +import androidx.compose.ui.res.dimensionResource
  38 +import androidx.compose.ui.res.stringResource
  39 +import androidx.compose.ui.unit.dp
  40 +import androidx.lifecycle.viewmodel.compose.viewModel
  41 +import androidx.navigation.NavHostController
  42 +import androidx.navigation.compose.NavHost
  43 +import androidx.navigation.compose.composable
  44 +import androidx.navigation.compose.currentBackStackEntryAsState
  45 +import androidx.navigation.compose.rememberNavController
  46 +import com.example.pizzaorder.ui.BurgerScreen
  47 +import com.example.pizzaorder.ui.ForgotPasswordScreen
  48 +import com.example.pizzaorder.ui.LoginScreen
  49 +import com.example.pizzaorder.ui.OrderPlacedScreen
  50 +import com.example.pizzaorder.ui.OrderSummaryScreen
  51 +import com.example.pizzaorder.ui.OrderViewModel
  52 +import com.example.pizzaorder.ui.PizzaScreen
  53 +import com.example.pizzaorder.ui.SignUpScreen
  54 +import com.example.pizzaorder.ui.StartOrderScreen
  55 +import com.google.firebase.auth.FirebaseAuth
  56 +
  57 +enum class PizzaScreenPages(@StringRes val title: Int) {
  58 + Login(title = R.string.login),
  59 + SignUp(title = R.string.signup),
  60 + ForgotPassword(title = R.string.forgot_password),
  61 + Start(title = R.string.start_order),
  62 + Pizza(title = R.string.choose_pizza_type),
  63 + Burger(title = R.string.choose_burger_type),
  64 + Pickup(title = R.string.choose_pickup_date),
  65 + Summary(title = R.string.order_summary),
  66 + OrderPlaced(title = R.string.order_placed)
  67 +}
  68 +
  69 +@OptIn(ExperimentalMaterial3Api::class)
  70 +@Composable
  71 +fun PizzaAppBar(
  72 + currentScreen: PizzaScreenPages,
  73 + canNavigateBack: Boolean,
  74 + navigateUp: () -> Unit,
  75 + onMenuClicked: () -> Unit,
  76 + modifier: Modifier = Modifier
  77 +) {
  78 + TopAppBar(
  79 + title = { Text(stringResource(currentScreen.title)) },
  80 + colors = TopAppBarDefaults.mediumTopAppBarColors(
  81 + containerColor = MaterialTheme.colorScheme.primaryContainer
  82 + ),
  83 + modifier = modifier,
  84 + navigationIcon = {
  85 + if (canNavigateBack) {
  86 + IconButton(onClick = navigateUp) {
  87 + Icon(
  88 + imageVector = Icons.AutoMirrored.Filled.ArrowBack,
  89 + contentDescription = stringResource(R.string.back_button)
  90 + )
  91 + }
  92 + }
  93 + },
  94 + actions = {
  95 + IconButton(onClick = onMenuClicked) {
  96 + Icon(
  97 + imageVector = Icons.Default.MoreVert,
  98 + contentDescription = stringResource(R.string.menu_button)
  99 + )
  100 + }
  101 + }
  102 + )
  103 +}
  104 +
  105 +@OptIn(ExperimentalMaterial3Api::class)
  106 +@Composable
  107 +fun PizzaApp(
  108 + viewModel: OrderViewModel = viewModel(),
  109 + navController: NavHostController = rememberNavController()
  110 +) {
  111 + val backStackEntry by navController.currentBackStackEntryAsState()
  112 + val currentScreen = PizzaScreenPages.valueOf(
  113 + backStackEntry?.destination?.route ?: PizzaScreenPages.Start.name
  114 + )
  115 + val isAuthenticated = FirebaseAuth.getInstance().currentUser != null
  116 +
  117 + var showBottomSheet by remember { mutableStateOf(false) }
  118 + var showLoginDialog by remember { mutableStateOf(false) }
  119 + val sheetState = rememberModalBottomSheetState()
  120 + val scope = rememberCoroutineScope()
  121 +
  122 +
  123 + if (showLoginDialog) {
  124 + AlertDialog(
  125 + onDismissRequest = {showLoginDialog = false},
  126 + title = { Text("Login Required") },
  127 + text = { Text("You need to log in to access this feature.") },
  128 + confirmButton = {
  129 + Button(onClick = {showLoginDialog = false}) {
  130 + Text("OK")
  131 + }
  132 + }
  133 + )
  134 + }
  135 +
  136 + if (showBottomSheet) {
  137 + ModalBottomSheet(
  138 + onDismissRequest = { showBottomSheet = false },
  139 + sheetState = sheetState
  140 + ) {
  141 + MenuContent(
  142 + onHomeClicked = {
  143 + showBottomSheet = false
  144 + if (isAuthenticated) {
  145 + navController.navigate(PizzaScreenPages.Start.name)
  146 + } else {
  147 + showLoginDialog = true
  148 + }
  149 +
  150 + },
  151 + onOrdersClicked = {
  152 + showBottomSheet = false
  153 + if (isAuthenticated) {
  154 + navController.navigate(PizzaScreenPages.Summary.name)
  155 + } else {
  156 + showLoginDialog = true
  157 + }
  158 +
  159 + },
  160 + onLogoutClicked = {
  161 + FirebaseAuth.getInstance().signOut()
  162 + showBottomSheet = false
  163 + navController.navigate(PizzaScreenPages.Login.name) {
  164 + popUpTo(PizzaScreenPages.Login.name) { inclusive = true }
  165 + }
  166 + }
  167 + )
  168 + }
  169 + }
  170 + Scaffold(
  171 + topBar = {
  172 + PizzaAppBar(
  173 + currentScreen = currentScreen,
  174 + canNavigateBack = navController.previousBackStackEntry != null,
  175 + navigateUp = { navController.navigateUp() },
  176 + onMenuClicked = { showBottomSheet = true }
  177 + )
  178 + },
  179 + bottomBar = {
  180 +
  181 + }
  182 + ) { innerPadding ->
  183 + val uiState by viewModel.uiState.collectAsState()
  184 +
  185 + NavHost(
  186 + navController = navController,
  187 + startDestination = if (isAuthenticated) PizzaScreenPages.Start.name else PizzaScreenPages.Login.name,
  188 + modifier = Modifier.padding(innerPadding)
  189 + ) {
  190 + composable(route = PizzaScreenPages.Login.name) {
  191 + LoginScreen(
  192 + navController = navController,
  193 + modifier = Modifier
  194 + .fillMaxSize()
  195 + .padding(dimensionResource(R.dimen.padding_medium))
  196 + )
  197 + }
  198 + composable(route = PizzaScreenPages.SignUp.name) {
  199 + SignUpScreen(
  200 + navController = navController,
  201 + modifier = Modifier
  202 + .fillMaxSize()
  203 + .padding(dimensionResource(R.dimen.padding_medium))
  204 + )
  205 + }
  206 + composable(route = PizzaScreenPages.ForgotPassword.name) {
  207 + ForgotPasswordScreen(
  208 + navController = navController,
  209 + modifier = Modifier
  210 + .fillMaxSize()
  211 + .padding(dimensionResource(R.dimen.padding_medium))
  212 + )
  213 + }
  214 + composable(route = PizzaScreenPages.Start.name) {
  215 + StartOrderScreen(
  216 + navController = navController,
  217 + modifier = Modifier.fillMaxSize())
  218 + }
  219 +
  220 + composable(route = PizzaScreenPages.Pizza.name) {
  221 + PizzaScreen(
  222 + viewModel = viewModel,
  223 + navController = navController)
  224 + }
  225 +
  226 + composable(route = PizzaScreenPages.Burger.name) {
  227 + BurgerScreen(
  228 + viewModel = viewModel,
  229 + navController = navController)
  230 + }
  231 + composable(route = PizzaScreenPages.Summary.name) {
  232 + OrderSummaryScreen(
  233 + viewModel = viewModel,
  234 + onBack = { navController.popBackStack() },
  235 + onPlace = { navController.navigate(PizzaScreenPages.OrderPlaced.name) })
  236 + }
  237 + composable(route = PizzaScreenPages.OrderPlaced.name) {
  238 + OrderPlacedScreen(
  239 + onBack = {
  240 + viewModel.clearOrder()
  241 + navController.navigate(PizzaScreenPages.Start.name) }
  242 + )
  243 + }
  244 + }
  245 + }
  246 +}
  247 +
  248 +@Composable
  249 +fun MenuContent(
  250 + onHomeClicked: () -> Unit,
  251 + onOrdersClicked: () -> Unit,
  252 + onLogoutClicked: () -> Unit
  253 +) {
  254 + Column(
  255 + modifier = Modifier
  256 + .fillMaxWidth()
  257 + .padding(16.dp),
  258 + verticalArrangement = Arrangement.spacedBy(16.dp)
  259 + ) {
  260 + Text(
  261 + text = "Menu",
  262 + style = MaterialTheme.typography.titleMedium,
  263 + modifier = Modifier.padding(bottom = 8.dp)
  264 + )
  265 + HorizontalDivider()
  266 + Button(
  267 + onClick = onHomeClicked,
  268 + modifier = Modifier.fillMaxWidth()
  269 + ) {
  270 + Text("Home")
  271 + }
  272 + Button(
  273 + onClick = onOrdersClicked,
  274 + modifier = Modifier.fillMaxWidth()
  275 + ) {
  276 + Text("Orders")
  277 + }
  278 + Button(
  279 + onClick = onLogoutClicked,
  280 + modifier = Modifier.fillMaxWidth(),
  281 + colors = ButtonDefaults.buttonColors(containerColor = Color.Red)
  282 + ) {
  283 + Text("Logout")
  284 + }
  285 + }
  286 +}
  1 +
  2 +package com.example.pizzaorder.data
  3 +
  4 +import com.example.pizzaorder.R
  5 +import com.example.pizzaorder.ui.MenuItem
  6 +
  7 +object DataSource {
  8 + val pizzaOptions = listOf(
  9 + MenuItem("Margherita Pizza", 8.99, R.drawable.pizza_marguerita, "Pizza"),
  10 + MenuItem("Pepperoni Pizza", 9.99, R.drawable.pizza_diavola, "Pizza"),
  11 + MenuItem("Quattro Formaggi", 10.99, R.drawable.pizza_quattro_formaggi, "Pizza"),
  12 + MenuItem("Capriciosa", 11.99, R.drawable.pizza_capricciosa, "Pizza")
  13 + )
  14 +
  15 + val burgerOptions = listOf(
  16 + MenuItem("Classic Burger", 6.99, R.drawable.classic_burger, "Burger"),
  17 + MenuItem("Cheeseburger", 7.49, R.drawable.cheeseburger, "Burger"),
  18 + MenuItem("Veggie Burger", 6.99, R.drawable.veggie_burger, "Burger"),
  19 + MenuItem("Bacon Burger", 8.99, R.drawable.bacon_burger, "Burger")
  20 + )
  21 +}
  1 +
  2 +package com.example.pizzaorder.data
  3 +
  4 +
  5 +data class OrderUiState(
  6 + val userEmail: String = "",
  7 + val firstName: String = "",
  8 + val lastName: String = "",
  9 + val address: String = "",
  10 + val quantity: Int = 0,
  11 + val pizzaType: String = "",
  12 + val date: String = "",
  13 + val price: String = "",
  14 + val pickupOptions: List<String> = listOf()
  15 +)
  1 +package com.example.pizzaorder.ui
  2 +
  3 +import androidx.compose.foundation.Image
  4 +import androidx.compose.foundation.layout.Box
  5 +import androidx.compose.foundation.layout.Column
  6 +import androidx.compose.foundation.layout.Row
  7 +import androidx.compose.foundation.layout.fillMaxSize
  8 +import androidx.compose.foundation.layout.fillMaxWidth
  9 +import androidx.compose.foundation.layout.padding
  10 +import androidx.compose.foundation.layout.size
  11 +import androidx.compose.foundation.lazy.LazyColumn
  12 +import androidx.compose.foundation.lazy.items
  13 +import androidx.compose.material.icons.Icons
  14 +import androidx.compose.material.icons.filled.Add
  15 +import androidx.compose.material.icons.filled.ArrowBack
  16 +import androidx.compose.material.icons.filled.Clear
  17 +import androidx.compose.material.icons.filled.KeyboardArrowDown
  18 +import androidx.compose.material.icons.filled.KeyboardArrowUp
  19 +import androidx.compose.material3.AlertDialog
  20 +import androidx.compose.material3.Button
  21 +import androidx.compose.material3.ButtonDefaults
  22 +import androidx.compose.material3.ExperimentalMaterial3Api
  23 +import androidx.compose.material3.HorizontalDivider
  24 +import androidx.compose.material3.Icon
  25 +import androidx.compose.material3.IconButton
  26 +import androidx.compose.material3.MaterialTheme
  27 +import androidx.compose.material3.OutlinedButton
  28 +import androidx.compose.material3.Scaffold
  29 +import androidx.compose.material3.Text
  30 +import androidx.compose.material3.TopAppBar
  31 +import androidx.compose.runtime.Composable
  32 +import androidx.compose.runtime.collectAsState
  33 +import androidx.compose.runtime.getValue
  34 +import androidx.compose.runtime.mutableStateOf
  35 +import androidx.compose.runtime.remember
  36 +import androidx.compose.runtime.setValue
  37 +import androidx.compose.ui.Alignment
  38 +import androidx.compose.ui.Modifier
  39 +import androidx.compose.ui.res.painterResource
  40 +import androidx.compose.ui.res.stringResource
  41 +import androidx.compose.ui.unit.dp
  42 +import androidx.navigation.NavHostController
  43 +import com.example.pizzaorder.PizzaScreenPages
  44 +import java.text.NumberFormat
  45 +
  46 +
  47 +@OptIn(ExperimentalMaterial3Api::class)
  48 +@Composable
  49 +fun BurgerScreen(viewModel: OrderViewModel, navController: NavHostController) {
  50 + val menuItems by viewModel.menuItems.collectAsState()
  51 + val totalPrice by viewModel.totalPrice.collectAsState()
  52 + var showDialog by remember { mutableStateOf(false) }
  53 +
  54 + Scaffold(
  55 +// topBar = {
  56 +// TopAppBar(
  57 +// title = { Text(stringResource(PizzaScreenPages.Burger.title)) },
  58 +// navigationIcon = {
  59 +// IconButton(onClick = { navController.navigateUp() }) {
  60 +// Icon(Icons.Default.ArrowBack, contentDescription = "Back")
  61 +// }
  62 +// }
  63 +// )
  64 +// }
  65 + ) { innerPadding ->
  66 + Column(
  67 + modifier = Modifier
  68 + .fillMaxSize()
  69 + .padding(innerPadding)
  70 + .padding(16.dp)
  71 + ) {
  72 + Text("Choose Your Burger", style = MaterialTheme.typography.headlineMedium)
  73 +
  74 + LazyColumn {
  75 + items(menuItems.filter { it.category == "Burger" }) { item ->
  76 + BurgerItemRow(item = item, onQuantityChanged = { quantity ->
  77 + viewModel.updateQuantity(item, quantity)
  78 + })
  79 + }
  80 + }
  81 +
  82 + HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
  83 +
  84 + Text("Total: $totalPrice", style = MaterialTheme.typography.headlineSmall)
  85 +
  86 + Button(
  87 + onClick = { showDialog = true },
  88 + modifier = Modifier.fillMaxWidth(),
  89 + colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error)
  90 + ) {
  91 + Text("Clear Order")
  92 + }
  93 +
  94 + Button(
  95 + onClick = { navController.navigate(PizzaScreenPages.Summary.name) },
  96 + modifier = Modifier.fillMaxWidth()
  97 + ) {
  98 + Text("Proceed to Order Summary")
  99 + }
  100 +
  101 + if (showDialog) {
  102 + AlertDialog(
  103 + onDismissRequest = { showDialog = false },
  104 + title = { Text("Confirm Clear Order") },
  105 + text = { Text("Are you sure you want to clear your order? This action cannot be undone.") },
  106 + confirmButton = {
  107 + Button(
  108 + onClick = {
  109 + viewModel.clearOrder()
  110 + showDialog = false
  111 + }
  112 + ) {
  113 + Text("Yes, Clear Order")
  114 + }
  115 + },
  116 + dismissButton = {
  117 + OutlinedButton(onClick = { showDialog = false }) {
  118 + Text("Cancel")
  119 + }
  120 + }
  121 + )
  122 + }
  123 + }
  124 + }
  125 +}
  126 +
  127 +@Composable
  128 +fun BurgerItemRow(item: MenuItem, onQuantityChanged: (Int) -> Unit) {
  129 + Row(
  130 + modifier = Modifier
  131 + .fillMaxWidth()
  132 + .padding(8.dp),
  133 + verticalAlignment = Alignment.CenterVertically
  134 + ) {
  135 + Box (
  136 + modifier = Modifier
  137 + .size(100.dp)
  138 + .padding(8.dp)
  139 + ){
  140 + Image(
  141 + painter = painterResource(id = item.imageRes),
  142 + contentDescription = item.name,
  143 + modifier = Modifier.size(80.dp)
  144 + )
  145 + }
  146 + Column(modifier = Modifier
  147 + .weight(1f)
  148 + .padding(start = 16.dp)) {
  149 + Text(item.name, style = MaterialTheme.typography.bodyLarge)
  150 + Text("Price: ${NumberFormat.getCurrencyInstance().format(item.price)}")
  151 + }
  152 + Row(verticalAlignment = Alignment.CenterVertically) {
  153 + IconButton(onClick = { if (item.quantity > 0) onQuantityChanged(item.quantity - 1) }) {
  154 + Icon(Icons.Default.KeyboardArrowDown, contentDescription = "Decrease")
  155 + }
  156 + Text(text = item.quantity.toString(), modifier = Modifier.padding(horizontal = 8.dp))
  157 + IconButton(onClick = { onQuantityChanged(item.quantity + 1) }) {
  158 + Icon(Icons.Default.KeyboardArrowUp, contentDescription = "Increase")
  159 + }
  160 + }
  161 + }
  162 +}
  1 +package com.example.pizzaorder.ui
  2 +
  3 +import androidx.compose.foundation.layout.Arrangement
  4 +import androidx.compose.foundation.layout.Column
  5 +import androidx.compose.foundation.layout.Spacer
  6 +import androidx.compose.foundation.layout.fillMaxWidth
  7 +import androidx.compose.foundation.layout.height
  8 +import androidx.compose.material3.Button
  9 +import androidx.compose.material3.Text
  10 +import androidx.compose.material3.TextField
  11 +import androidx.compose.runtime.Composable
  12 +import androidx.compose.runtime.getValue
  13 +import androidx.compose.runtime.mutableStateOf
  14 +import androidx.compose.runtime.remember
  15 +import androidx.compose.runtime.setValue
  16 +import androidx.compose.ui.Alignment
  17 +import androidx.compose.ui.Modifier
  18 +import androidx.compose.ui.graphics.Color
  19 +import androidx.compose.ui.res.dimensionResource
  20 +import androidx.compose.ui.res.stringResource
  21 +import androidx.navigation.NavHostController
  22 +import com.example.pizzaorder.R
  23 +import com.google.firebase.auth.FirebaseAuth
  24 +
  25 +@Composable
  26 +fun ForgotPasswordScreen(
  27 + navController: NavHostController,
  28 + modifier: Modifier = Modifier
  29 +) {
  30 + var email by remember { mutableStateOf("") }
  31 + var message by remember { mutableStateOf("") }
  32 +
  33 + Column(
  34 + modifier = modifier,
  35 + verticalArrangement = Arrangement.Center,
  36 + horizontalAlignment = Alignment.CenterHorizontally
  37 + ) {
  38 + TextField(
  39 + value = email,
  40 + onValueChange = { email = it },
  41 + label = { Text(stringResource(R.string.forgot_email_field)) },
  42 + modifier = Modifier.fillMaxWidth()
  43 + )
  44 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_medium)))
  45 + Button(
  46 + onClick = {
  47 + FirebaseAuth.getInstance().sendPasswordResetEmail(email)
  48 + .addOnCompleteListener { task ->
  49 + if (task.isSuccessful) {
  50 + message = "Password reset email sent."
  51 + } else {
  52 + message = task.exception?.message ?: "Failed to send email."
  53 + }
  54 + }
  55 + },
  56 + modifier = Modifier.fillMaxWidth()
  57 + ) {
  58 + Text(stringResource(R.string.forgot_password_button))
  59 + }
  60 + if (message.isNotEmpty()) {
  61 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
  62 + Text(message, color = if (message.contains("sent")) Color.Green else Color.Red)
  63 + }
  64 + }
  65 +}
  1 +package com.example.pizzaorder.ui
  2 +
  3 +import androidx.compose.foundation.layout.Arrangement
  4 +import androidx.compose.foundation.layout.Column
  5 +import androidx.compose.foundation.layout.Spacer
  6 +import androidx.compose.foundation.layout.fillMaxSize
  7 +import androidx.compose.foundation.layout.fillMaxWidth
  8 +import androidx.compose.foundation.layout.height
  9 +import androidx.compose.material3.Button
  10 +import androidx.compose.material3.Text
  11 +import androidx.compose.material3.TextField
  12 +import androidx.compose.runtime.Composable
  13 +import androidx.compose.runtime.getValue
  14 +import androidx.compose.runtime.mutableStateOf
  15 +import androidx.compose.runtime.remember
  16 +import androidx.compose.runtime.setValue
  17 +import androidx.compose.ui.Alignment
  18 +import androidx.compose.ui.Modifier
  19 +import androidx.compose.ui.graphics.Color
  20 +import androidx.compose.ui.res.dimensionResource
  21 +import androidx.compose.ui.res.stringResource
  22 +import androidx.compose.ui.text.input.PasswordVisualTransformation
  23 +import androidx.compose.ui.tooling.preview.Preview
  24 +import androidx.navigation.NavController
  25 +import androidx.navigation.NavHostController
  26 +import androidx.navigation.compose.rememberNavController
  27 +import com.example.pizzaorder.PizzaScreenPages
  28 +import com.example.pizzaorder.R
  29 +import com.example.pizzaorder.ui.theme.PizzaTheme
  30 +import com.google.firebase.auth.FirebaseAuth
  31 +
  32 +@Composable
  33 +fun LoginScreen(
  34 + //onLoginButtonClicked: @Composable () -> Unit,
  35 + navController: NavHostController = rememberNavController(),
  36 + modifier: Modifier = Modifier
  37 +) {
  38 + var username by remember { mutableStateOf("") }
  39 + var password by remember { mutableStateOf("") }
  40 + var showDialog by remember { mutableStateOf(false) }
  41 + var errorMessage by remember { mutableStateOf("") }
  42 +
  43 + Column (
  44 + modifier = modifier,
  45 + verticalArrangement = Arrangement.Center,
  46 + horizontalAlignment = Alignment.CenterHorizontally
  47 + ) {
  48 + TextField(
  49 + value = username,
  50 + onValueChange = { username = it },
  51 + label = {Text(stringResource(R.string.login_user_field))},
  52 + modifier = Modifier.fillMaxWidth()
  53 + )
  54 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
  55 + TextField(
  56 + value = password,
  57 + onValueChange = { password = it },
  58 + label = {Text(stringResource(R.string.login_passwd_field))},
  59 + visualTransformation = PasswordVisualTransformation(),
  60 + modifier = Modifier.fillMaxWidth()
  61 + )
  62 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_medium)))
  63 + Button(
  64 + onClick = { handleLogin(
  65 + username = username,
  66 + password = password,
  67 + navController = navController,
  68 + showDialogUpdater = { show, message ->
  69 + showDialog = show
  70 + errorMessage = message
  71 + })
  72 + },
  73 + modifier = Modifier.fillMaxWidth()
  74 + ) {
  75 + Text(stringResource(R.string.login_button))
  76 + }
  77 + if (errorMessage.isNotEmpty()) {
  78 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
  79 + Text(errorMessage, color = Color.Red)
  80 + }
  81 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
  82 + Button(
  83 + onClick = { navController.navigate(PizzaScreenPages.SignUp.name) },
  84 + modifier = Modifier.fillMaxWidth()
  85 + ) {
  86 + Text(stringResource(R.string.signup_button))
  87 + }
  88 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
  89 + Button(
  90 + onClick = { navController.navigate(PizzaScreenPages.ForgotPassword.name) },
  91 + modifier = Modifier.fillMaxWidth()
  92 + ) {
  93 + Text(stringResource(R.string.forgot_password_button))
  94 + }
  95 +
  96 + }
  97 +
  98 +
  99 +}
  100 +
  101 +private fun handleLogin(
  102 + username: String,
  103 + password: String,
  104 + navController: NavController,
  105 + showDialogUpdater: (Boolean, String) -> Unit
  106 +) {
  107 + //if (username == "user" && password == "password") {
  108 +// if (username == "" && password == "") {
  109 +// navController.navigate(PizzaScreenPages.Start.name)
  110 +// return true
  111 +// } else {
  112 +// showDialogUpdater(true, "Invalid username or password.")
  113 +// return false
  114 +// }
  115 + if (username.isEmpty() || password.isEmpty()) {
  116 + showDialogUpdater(true, "Add the username(email) and the password!")
  117 + return
  118 + }
  119 +
  120 + FirebaseAuth.getInstance().signInWithEmailAndPassword(username, password)
  121 + .addOnCompleteListener {task ->
  122 + if (task.isSuccessful) {
  123 + navController.navigate(PizzaScreenPages.Start.name)
  124 + } else {
  125 + showDialogUpdater(true, task.exception?.message ?: "Adresă de mail sau parolă incorectă")
  126 + }
  127 + }
  128 +}
  129 +
  130 +
  131 +@Preview
  132 +@Composable
  133 +fun LoginScreenPreview() {
  134 + PizzaTheme {
  135 + LoginScreen(
  136 + navController = rememberNavController(),
  137 + modifier = Modifier
  138 + .fillMaxSize()
  139 + )
  140 + }
  141 +}
  1 +package com.example.pizzaorder.ui
  2 +
  3 +import androidx.compose.foundation.layout.*
  4 +import androidx.compose.material3.*
  5 +import androidx.compose.runtime.Composable
  6 +import androidx.compose.ui.Alignment
  7 +import androidx.compose.ui.Modifier
  8 +import androidx.compose.ui.res.stringResource
  9 +import androidx.compose.ui.text.style.TextAlign
  10 +import androidx.compose.ui.unit.dp
  11 +import androidx.navigation.NavHostController
  12 +import com.example.pizzaorder.PizzaScreenPages
  13 +import com.example.pizzaorder.R
  14 +
  15 +@Composable
  16 +fun OrderPlacedScreen(onBack: () -> Unit) {
  17 + Column(
  18 + modifier = Modifier
  19 + .fillMaxSize()
  20 + .padding(16.dp),
  21 + verticalArrangement = Arrangement.Center,
  22 + horizontalAlignment = Alignment.CenterHorizontally
  23 + ) {
  24 + Text(
  25 + text = "Order Placed!",
  26 + style = MaterialTheme.typography.headlineMedium,
  27 + textAlign = TextAlign.Center
  28 + )
  29 + Spacer(modifier = Modifier.height(16.dp))
  30 + Text(
  31 + text = "Thank you for your order. Your food will be prepared shortly!",
  32 + style = MaterialTheme.typography.bodyLarge,
  33 + textAlign = TextAlign.Center
  34 + )
  35 + Spacer(modifier = Modifier.height(32.dp))
  36 + Button(
  37 + onClick = onBack,
  38 + modifier = Modifier.fillMaxWidth()
  39 + ) {
  40 + Text("Back to Home")
  41 + }
  42 + }
  43 +}
  1 +package com.example.pizzaorder.ui
  2 +
  3 +import androidx.lifecycle.ViewModel
  4 +import androidx.lifecycle.viewModelScope
  5 +import com.example.pizzaorder.R
  6 +import com.example.pizzaorder.data.OrderUiState
  7 +import com.google.firebase.auth.FirebaseAuth
  8 +import com.google.firebase.firestore.FirebaseFirestore
  9 +import kotlinx.coroutines.flow.MutableStateFlow
  10 +import kotlinx.coroutines.flow.SharingStarted
  11 +import kotlinx.coroutines.flow.StateFlow
  12 +import kotlinx.coroutines.flow.asStateFlow
  13 +import kotlinx.coroutines.flow.map
  14 +import kotlinx.coroutines.flow.stateIn
  15 +import kotlinx.coroutines.flow.update
  16 +import java.text.NumberFormat
  17 +
  18 +
  19 +data class MenuItem(
  20 + val name: String,
  21 + val price: Double,
  22 + val imageRes: Int,
  23 + val category: String,
  24 + val quantity: Int = 0,
  25 +)
  26 +
  27 +class OrderViewModel : ViewModel() {
  28 +
  29 + private val auth: FirebaseAuth = FirebaseAuth.getInstance()
  30 + private val database: FirebaseFirestore = FirebaseFirestore.getInstance()
  31 +
  32 + private val _uiState = MutableStateFlow(
  33 + OrderUiState(
  34 + userEmail = auth.currentUser?.email ?: "Guest",
  35 + firstName = "",
  36 + lastName = "",
  37 + address = ""
  38 + )
  39 + )
  40 +
  41 + val uiState: StateFlow<OrderUiState> = _uiState.asStateFlow()
  42 +
  43 + init {
  44 + fetchUserDetails()
  45 + }
  46 +
  47 +
  48 + private val _menuItems = MutableStateFlow(
  49 + listOf(
  50 + MenuItem("Marguerita", 8.99, R.drawable.pizza_marguerita, "Pizza"),
  51 + MenuItem("Diavola", 9.99, R.drawable.pizza_diavola, "Pizza"),
  52 + MenuItem("Quattro Formaggi", 10.99, R.drawable.pizza_quattro_formaggi, "Pizza"),
  53 + MenuItem("Capricciosa", 11.99, R.drawable.pizza_capricciosa, "Pizza"),
  54 + MenuItem("Classic Burger", 6.99, R.drawable.classic_burger, "Burger"),
  55 + MenuItem("Cheeseburger", 7.49, R.drawable.cheeseburger, "Burger"),
  56 + MenuItem("Veggie Burger", 6.99, R.drawable.veggie_burger, "Burger"),
  57 + MenuItem("Bacon Burger", 8.99, R.drawable.bacon_burger, "Burger")
  58 + )
  59 + )
  60 +
  61 + val menuItems: StateFlow<List<MenuItem>> = _menuItems.asStateFlow()
  62 +
  63 + val _selectedItems = MutableStateFlow<List<Pair<String, Double>>>(emptyList())
  64 +
  65 +// val selectedItems: StateFlow<List<Pair<String, Double>>> = _selectedItems.asStateFlow()
  66 +
  67 + val selectedItems: StateFlow<List<MenuItem>> = _menuItems
  68 + .map { it.filter { item -> item.quantity > 0 } }
  69 + .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
  70 +
  71 +
  72 + fun updateQuantity(item: MenuItem, newQuantity: Int) {
  73 + _menuItems.update { currentList ->
  74 + currentList.map { if (it.name == item.name) it.copy(quantity = newQuantity) else it }
  75 + }
  76 + }
  77 +
  78 + val totalPrice: StateFlow<String> = _menuItems.map { list ->
  79 + val total = list.sumOf { it.price * it.quantity }
  80 + NumberFormat.getCurrencyInstance().format(total)
  81 + }.stateIn(viewModelScope, SharingStarted.Eagerly, "$0.00")
  82 +
  83 +
  84 + private fun fetchUserDetails() {
  85 + auth.currentUser?.let { user ->
  86 + database.collection("users").document(user.uid).get()
  87 + .addOnSuccessListener { document ->
  88 + val firstName = document.getString("firstName") ?: ""
  89 + val lastName = document.getString("lastName") ?: ""
  90 + val address = document.getString("address") ?: ""
  91 +
  92 + _uiState.update {
  93 + it.copy(
  94 + firstName = firstName,
  95 + lastName = lastName,
  96 + address = address
  97 + )
  98 + }
  99 + }
  100 + }
  101 + }
  102 +
  103 + fun isAuthenticated(): Boolean {
  104 + return auth.currentUser != null
  105 +
  106 + }
  107 +
  108 +
  109 + fun clearItems() {
  110 + _selectedItems.value = emptyList()
  111 + }
  112 +
  113 + fun resetOrder() {
  114 + _uiState.value = OrderUiState(
  115 +// pickupOptions = pickupOptions(),
  116 + userEmail = auth.currentUser?.email ?: "Guest"
  117 + )
  118 + clearItems() // Clear selected items when resetting the order
  119 + }
  120 +
  121 + fun clearOrder() {
  122 + _menuItems.update { currentList ->
  123 + currentList.map {it.copy(quantity = 0)}
  124 + }
  125 + }
  126 +
  127 +}
  1 +package com.example.pizzaorder.ui
  2 +
  3 +
  4 +import androidx.compose.foundation.Image
  5 +import androidx.compose.foundation.layout.Box
  6 +import androidx.compose.foundation.layout.Column
  7 +import androidx.compose.foundation.layout.Row
  8 +import androidx.compose.foundation.layout.fillMaxSize
  9 +import androidx.compose.foundation.layout.fillMaxWidth
  10 +import androidx.compose.foundation.layout.padding
  11 +import androidx.compose.foundation.layout.size
  12 +import androidx.compose.foundation.lazy.LazyColumn
  13 +import androidx.compose.foundation.lazy.items
  14 +import androidx.compose.material.icons.Icons
  15 +import androidx.compose.material.icons.filled.KeyboardArrowDown
  16 +import androidx.compose.material.icons.filled.KeyboardArrowUp
  17 +import androidx.compose.material3.AlertDialog
  18 +import androidx.compose.material3.Button
  19 +import androidx.compose.material3.ButtonDefaults
  20 +import androidx.compose.material3.ExperimentalMaterial3Api
  21 +import androidx.compose.material3.HorizontalDivider
  22 +import androidx.compose.material3.Icon
  23 +import androidx.compose.material3.IconButton
  24 +import androidx.compose.material3.MaterialTheme
  25 +import androidx.compose.material3.OutlinedButton
  26 +import androidx.compose.material3.Scaffold
  27 +import androidx.compose.material3.Text
  28 +import androidx.compose.runtime.Composable
  29 +import androidx.compose.runtime.collectAsState
  30 +import androidx.compose.runtime.getValue
  31 +import androidx.compose.runtime.mutableStateOf
  32 +import androidx.compose.runtime.remember
  33 +import androidx.compose.runtime.setValue
  34 +import androidx.compose.ui.Alignment
  35 +import androidx.compose.ui.Modifier
  36 +import androidx.compose.ui.layout.ContentScale
  37 +import androidx.compose.ui.res.painterResource
  38 +import androidx.compose.ui.unit.dp
  39 +import androidx.navigation.NavHostController
  40 +import com.example.pizzaorder.PizzaScreenPages
  41 +import java.text.NumberFormat
  42 +
  43 +
  44 +@OptIn(ExperimentalMaterial3Api::class)
  45 +@Composable
  46 +fun PizzaScreen(viewModel: OrderViewModel, navController: NavHostController) {
  47 + val menuItems by viewModel.menuItems.collectAsState()
  48 + val totalPrice by viewModel.totalPrice.collectAsState()
  49 + var showDialog by remember { mutableStateOf(false) }
  50 +
  51 + Scaffold(
  52 +// topBar = {
  53 +// TopAppBar(
  54 +// title = { Text(stringResource(PizzaScreenPages.Pizza.title)) },
  55 +// navigationIcon = {
  56 +// IconButton(onClick = { navController.navigateUp() }) {
  57 +// Icon(Icons.Default.ArrowBack, contentDescription = "Back")
  58 +// }
  59 +// }
  60 +// )
  61 +// }
  62 + ) { innerPadding ->
  63 + Column(
  64 + modifier = Modifier
  65 + .fillMaxSize()
  66 + .padding(innerPadding)
  67 + .padding(16.dp)
  68 + ) {
  69 + Text("Choose Your Pizza", style = MaterialTheme.typography.headlineMedium)
  70 +
  71 + LazyColumn {
  72 + items(menuItems.filter { it.category == "Pizza" }) { item ->
  73 + PizzaItemRow(item = item, onQuantityChanged = { quantity ->
  74 + viewModel.updateQuantity(item, quantity)
  75 + })
  76 + }
  77 + }
  78 +
  79 + HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
  80 +
  81 + Text("Total: $totalPrice", style = MaterialTheme.typography.headlineSmall)
  82 +
  83 + Button(
  84 + onClick = { showDialog = true },
  85 + modifier = Modifier.fillMaxWidth(),
  86 + colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error)
  87 + ) {
  88 + Text("Clear Order")
  89 + }
  90 +
  91 + Button(
  92 + onClick = { navController.navigate(PizzaScreenPages.Summary.name) },
  93 + modifier = Modifier.fillMaxWidth()
  94 + ) {
  95 + Text("Proceed to Order Summary")
  96 + }
  97 +
  98 + if (showDialog) {
  99 + AlertDialog(
  100 + onDismissRequest = { showDialog = false },
  101 + title = { Text("Confirm Clear Order") },
  102 + text = { Text("Are you sure you want to clear your order? This action cannot be undone.") },
  103 + confirmButton = {
  104 + Button(
  105 + onClick = {
  106 + viewModel.clearOrder()
  107 + showDialog = false
  108 + }
  109 + ) {
  110 + Text("Yes, Clear Order")
  111 + }
  112 + },
  113 + dismissButton = {
  114 + OutlinedButton(onClick = { showDialog = false }) {
  115 + Text("Cancel")
  116 + }
  117 + }
  118 + )
  119 + }
  120 +
  121 + }
  122 + }
  123 +}
  124 +
  125 +@Composable
  126 +fun PizzaItemRow(item: MenuItem, onQuantityChanged: (Int) -> Unit) {
  127 + Row(
  128 + modifier = Modifier
  129 + .fillMaxWidth()
  130 + .padding(8.dp),
  131 + verticalAlignment = Alignment.CenterVertically
  132 + ) {
  133 + Box (
  134 + modifier = Modifier
  135 + .size(100.dp)
  136 + .padding(8.dp)
  137 + ) {
  138 + Image(
  139 + painter = painterResource(id = item.imageRes),
  140 + contentDescription = item.name,
  141 + // modifier = Modifier.size(80.dp)
  142 + modifier = Modifier.fillMaxSize(),
  143 + contentScale = ContentScale.Crop
  144 + )
  145 + }
  146 + Column(modifier = Modifier
  147 + .weight(1f)
  148 + .padding(start = 16.dp)) {
  149 + Text(item.name, style = MaterialTheme.typography.bodyLarge)
  150 + Text("Price: ${NumberFormat.getCurrencyInstance().format(item.price)}")
  151 + }
  152 + Row(verticalAlignment = Alignment.CenterVertically) {
  153 + IconButton(onClick = { if (item.quantity > 0) onQuantityChanged(item.quantity - 1) }) {
  154 + Icon(Icons.Default.KeyboardArrowDown, contentDescription = "Decrease")
  155 + }
  156 + Text(text = item.quantity.toString(), modifier = Modifier.padding(horizontal = 8.dp))
  157 + IconButton(onClick = { onQuantityChanged(item.quantity + 1) }) {
  158 + Icon(Icons.Default.KeyboardArrowUp, contentDescription = "Increase")
  159 + }
  160 + }
  161 + }
  162 +}
  163 +
  164 +
  165 +
  166 +
  167 +
  168 +
  169 +//@Composable
  170 +//fun PizzaScreen(
  171 +// viewModel: OrderViewModel,
  172 +// navController: NavHostController
  173 +//) {
  174 +// SelectOptionScreen(
  175 +// title = stringResource(R.string.order_pizza),
  176 +// options = listOf(
  177 +// "Margherita" to 8.99,
  178 +// "Pepperoni" to 9.99,
  179 +// "BBQ Chicken" to 10.99,
  180 +// "Veggie Delight" to 7.99
  181 +// ),
  182 +// onAddItem = { item, price -> viewModel.addItem(item, price)},
  183 +// onBack = { navController.popBackStack() }
  184 +// )
  185 +//}
  1 +package com.example.pizzaorder.ui
  2 +
  3 +import androidx.compose.foundation.layout.Arrangement
  4 +import androidx.compose.foundation.layout.Column
  5 +import androidx.compose.foundation.layout.Row
  6 +import androidx.compose.foundation.layout.fillMaxSize
  7 +import androidx.compose.foundation.layout.fillMaxWidth
  8 +import androidx.compose.foundation.layout.padding
  9 +import androidx.compose.material3.Button
  10 +import androidx.compose.material3.MaterialTheme
  11 +import androidx.compose.material3.Text
  12 +import androidx.compose.runtime.Composable
  13 +import androidx.compose.ui.Modifier
  14 +import androidx.compose.ui.res.dimensionResource
  15 +import androidx.compose.ui.res.stringResource
  16 +import com.example.pizzaorder.R
  17 +import java.text.NumberFormat
  18 +
  19 +
  20 +//@Composable
  21 +//fun SelectOptionScreen(
  22 +// title: String,
  23 +// options: List<Pair<String, Double>>,
  24 +// onAddItem: (String, Double) -> Unit,
  25 +// onBack: () -> Unit,
  26 +// modifier: Modifier = Modifier
  27 +//) {
  28 +// Column(
  29 +// modifier = modifier
  30 +// .fillMaxSize()
  31 +// .padding(dimensionResource(R.dimen.padding_medium)),
  32 +// verticalArrangement = Arrangement.SpaceBetween
  33 +// ) {
  34 +// Text(
  35 +// text = title,
  36 +// style = MaterialTheme.typography.headlineMedium,
  37 +// modifier = Modifier.padding(bottom = dimensionResource(R.dimen.padding_medium))
  38 +// )
  39 +// options.forEach { (name, price) ->
  40 +// Row(
  41 +// modifier = Modifier
  42 +// .fillMaxWidth()
  43 +// .padding(vertical = dimensionResource(R.dimen.padding_small)),
  44 +// horizontalArrangement = Arrangement.SpaceBetween
  45 +// ) {
  46 +// Text(name)
  47 +// Button(onClick = { onAddItem(name, price) }) {
  48 +// Text("Add (${NumberFormat.getCurrencyInstance().format(price)})")
  49 +// }
  50 +// }
  51 +// }
  52 +// Button(
  53 +// onClick = onBack,
  54 +// modifier = Modifier.fillMaxWidth()
  55 +// ) {
  56 +// Text(stringResource(R.string.back_to_menu))
  57 +// }
  58 +// }
  59 +//}
  60 +//
  1 +package com.example.pizzaorder.ui
  2 +
  3 +import androidx.compose.foundation.layout.Arrangement
  4 +import androidx.compose.foundation.layout.Column
  5 +import androidx.compose.foundation.layout.Spacer
  6 +import androidx.compose.foundation.layout.fillMaxWidth
  7 +import androidx.compose.foundation.layout.height
  8 +import androidx.compose.material3.Button
  9 +import androidx.compose.material3.Text
  10 +import androidx.compose.material3.TextField
  11 +import androidx.compose.runtime.Composable
  12 +import androidx.compose.runtime.getValue
  13 +import androidx.compose.runtime.mutableStateOf
  14 +import androidx.compose.runtime.remember
  15 +import androidx.compose.runtime.setValue
  16 +import androidx.compose.ui.Alignment
  17 +import androidx.compose.ui.Modifier
  18 +import androidx.compose.ui.graphics.Color
  19 +import androidx.compose.ui.res.dimensionResource
  20 +import androidx.compose.ui.res.stringResource
  21 +import androidx.compose.ui.text.input.PasswordVisualTransformation
  22 +import androidx.navigation.NavHostController
  23 +import com.example.pizzaorder.PizzaScreenPages
  24 +import com.example.pizzaorder.R
  25 +import com.google.firebase.auth.FirebaseAuth
  26 +import com.google.firebase.firestore.FirebaseFirestore
  27 +
  28 +@Composable
  29 +fun SignUpScreen(
  30 + navController: NavHostController,
  31 + modifier: Modifier = Modifier
  32 +) {
  33 + var email by remember { mutableStateOf("") }
  34 + var password by remember { mutableStateOf("") }
  35 + var confirmPassword by remember { mutableStateOf("") }
  36 + var firstName by remember { mutableStateOf("") }
  37 + var lastName by remember { mutableStateOf("") }
  38 + var address by remember { mutableStateOf("") }
  39 + var errorMessage by remember { mutableStateOf("") }
  40 +
  41 + val auth = FirebaseAuth.getInstance()
  42 + val database = FirebaseFirestore.getInstance()
  43 +
  44 + Column(
  45 + modifier = modifier,
  46 + verticalArrangement = Arrangement.Center,
  47 + horizontalAlignment = Alignment.CenterHorizontally
  48 + ) {
  49 + TextField(
  50 + value = firstName,
  51 + onValueChange = { firstName = it },
  52 + label = { Text("First Name") },
  53 + modifier = Modifier.fillMaxWidth()
  54 + )
  55 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
  56 + TextField(
  57 + value = lastName,
  58 + onValueChange = { lastName = it },
  59 + label = { Text("Last Name") },
  60 + modifier = Modifier.fillMaxWidth()
  61 + )
  62 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
  63 + TextField(
  64 + value = address,
  65 + onValueChange = { address = it },
  66 + label = { Text("Address") },
  67 + modifier = Modifier.fillMaxWidth()
  68 + )
  69 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
  70 + TextField(
  71 + value = email,
  72 + onValueChange = { email = it },
  73 + label = { Text(stringResource(R.string.signup_email_field)) },
  74 + modifier = Modifier.fillMaxWidth()
  75 + )
  76 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
  77 + TextField(
  78 + value = password,
  79 + onValueChange = { password = it },
  80 + label = { Text(stringResource(R.string.signup_password_field)) },
  81 + visualTransformation = PasswordVisualTransformation(),
  82 + modifier = Modifier.fillMaxWidth()
  83 + )
  84 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
  85 + TextField(
  86 + value = confirmPassword,
  87 + onValueChange = { confirmPassword = it },
  88 + label = { Text(stringResource(R.string.signup_confirm_password_field)) },
  89 + visualTransformation = PasswordVisualTransformation(),
  90 + modifier = Modifier.fillMaxWidth()
  91 + )
  92 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_medium)))
  93 + Button(
  94 + onClick = {
  95 + if (!isValidEmail(email)) {
  96 + errorMessage = "Please enter a valid email address."
  97 + } else if (password.length < 6) {
  98 + errorMessage = "Password must be at least 6 characters long."
  99 + } else if (password != confirmPassword) {
  100 + errorMessage = "Passwords do not match."
  101 + } else {
  102 + FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
  103 + .addOnCompleteListener { task ->
  104 + if (task.isSuccessful) {
  105 + val userId = auth.currentUser?.uid ?: return@addOnCompleteListener
  106 + val user = hashMapOf(
  107 + "firstName" to firstName,
  108 + "lastName" to lastName,
  109 + "address" to address,
  110 + "email" to email
  111 + )
  112 + database.collection("users").document(userId).set(user)
  113 + .addOnCompleteListener {
  114 + navController.navigate(PizzaScreenPages.Login.name)
  115 + }
  116 + } else {
  117 + errorMessage = task.exception?.message ?: "Sign-Up failed."
  118 + }
  119 + }
  120 + }
  121 + },
  122 + modifier = Modifier.fillMaxWidth()
  123 + ) {
  124 + Text(stringResource(R.string.signup_button))
  125 + }
  126 + if (errorMessage.isNotEmpty()) {
  127 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
  128 + Text(errorMessage, color = Color.Red)
  129 + }
  130 + }
  131 +}
  132 +
  133 +private fun isValidEmail(email: String): Boolean {
  134 + return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
  135 +}
  1 +
  2 +package com.example.pizzaorder.ui
  3 +
  4 +import androidx.compose.foundation.layout.Arrangement
  5 +import androidx.compose.foundation.layout.Column
  6 +import androidx.compose.foundation.layout.Spacer
  7 +import androidx.compose.foundation.layout.fillMaxSize
  8 +import androidx.compose.foundation.layout.fillMaxWidth
  9 +import androidx.compose.foundation.layout.height
  10 +import androidx.compose.foundation.layout.padding
  11 +import androidx.compose.material3.Button
  12 +import androidx.compose.material3.Text
  13 +import androidx.compose.runtime.Composable
  14 +import androidx.compose.ui.Alignment
  15 +import androidx.compose.ui.Modifier
  16 +import androidx.compose.ui.res.dimensionResource
  17 +import androidx.compose.ui.res.stringResource
  18 +import androidx.lifecycle.viewmodel.compose.viewModel
  19 +import androidx.navigation.NavHostController
  20 +import com.example.pizzaorder.PizzaScreenPages
  21 +import com.example.pizzaorder.R
  22 +
  23 +
  24 +@Composable
  25 +fun StartOrderScreen(
  26 + viewModel: OrderViewModel = viewModel(),
  27 + navController: NavHostController,
  28 + modifier: Modifier = Modifier
  29 +) {
  30 + Column(
  31 + modifier = modifier
  32 + .fillMaxSize()
  33 + .padding(dimensionResource(R.dimen.padding_medium)),
  34 + verticalArrangement = Arrangement.Center,
  35 + horizontalAlignment = Alignment.CenterHorizontally
  36 + ) {
  37 + Button(
  38 + onClick = { navController.navigate(PizzaScreenPages.Pizza.name) },
  39 + modifier = Modifier
  40 + .fillMaxWidth()
  41 + .padding(vertical = dimensionResource(R.dimen.padding_small))
  42 + ) {
  43 + Text(stringResource(R.string.order_pizza))
  44 + }
  45 + Button(
  46 + onClick = { navController.navigate(PizzaScreenPages.Burger.name) },
  47 + modifier = Modifier
  48 + .fillMaxWidth()
  49 + .padding(vertical = dimensionResource(R.dimen.padding_small))
  50 + ) {
  51 + Text(stringResource(R.string.order_burgers))
  52 + }
  53 + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_medium)))
  54 + Button(
  55 + onClick = { navController.navigate(PizzaScreenPages.Summary.name) },
  56 + modifier = Modifier.fillMaxWidth()
  57 + ) {
  58 + Text(stringResource(R.string.view_order_summary))
  59 + }
  60 + }
  61 +}
  62 +
  1 +package com.example.pizzaorder.ui
  2 +
  3 +import android.content.Context
  4 +import android.content.Intent
  5 +import androidx.compose.foundation.layout.Arrangement
  6 +import androidx.compose.foundation.layout.Column
  7 +import androidx.compose.foundation.layout.Row
  8 +import androidx.compose.foundation.layout.fillMaxSize
  9 +import androidx.compose.foundation.layout.fillMaxWidth
  10 +import androidx.compose.foundation.layout.padding
  11 +import androidx.compose.material3.AlertDialog
  12 +import androidx.compose.material3.Button
  13 +import androidx.compose.material3.ButtonDefaults
  14 +import androidx.compose.material3.Divider
  15 +import androidx.compose.material3.HorizontalDivider
  16 +import androidx.compose.material3.MaterialTheme
  17 +import androidx.compose.material3.OutlinedButton
  18 +import androidx.compose.material3.Text
  19 +import androidx.compose.runtime.Composable
  20 +import androidx.compose.runtime.collectAsState
  21 +import androidx.compose.runtime.getValue
  22 +import androidx.compose.runtime.mutableStateOf
  23 +import androidx.compose.runtime.remember
  24 +import androidx.compose.runtime.setValue
  25 +import androidx.compose.ui.Modifier
  26 +import androidx.compose.ui.platform.LocalContext
  27 +import androidx.compose.ui.tooling.preview.Preview
  28 +import androidx.compose.ui.unit.dp
  29 +import com.example.pizzaorder.PizzaScreenPages
  30 +import com.example.pizzaorder.R
  31 +import com.example.pizzaorder.ui.theme.PizzaTheme
  32 +import java.text.NumberFormat
  33 +
  34 +
  35 +@Composable
  36 +fun OrderSummaryScreen(
  37 + viewModel: OrderViewModel,
  38 + onBack: () -> Unit,
  39 + onPlace: () -> Unit
  40 +) {
  41 + val selectedItems by viewModel.selectedItems.collectAsState()
  42 + val totalPrice = viewModel.totalPrice.collectAsState().value
  43 + var showDialog by remember { mutableStateOf(false) }
  44 + val context = LocalContext.current
  45 +
  46 + Column(
  47 + modifier = Modifier
  48 + .fillMaxSize()
  49 + .padding(16.dp),
  50 + verticalArrangement = Arrangement.spacedBy(12.dp)
  51 + ) {
  52 + Text("Order Summary", style = MaterialTheme.typography.headlineMedium)
  53 + selectedItems.filter { it.quantity > 0 }.forEach { item ->
  54 + Row(
  55 + modifier = Modifier.fillMaxWidth(),
  56 + horizontalArrangement = Arrangement.SpaceBetween
  57 + ) {
  58 + Text("${item.name} x${item.quantity}")
  59 + Text(NumberFormat.getCurrencyInstance().format(item.price * item.quantity))
  60 + }
  61 + }
  62 + HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
  63 + Text("Total: $totalPrice", style = MaterialTheme.typography.headlineSmall)
  64 + Column (
  65 + modifier = Modifier.fillMaxWidth(),
  66 + verticalArrangement = Arrangement.spacedBy(8.dp) // ✅ Reduce button spacing
  67 + ) {
  68 + Button(
  69 + onClick = { showDialog = true },
  70 + modifier = Modifier.fillMaxWidth(),
  71 + colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error)
  72 + ) {
  73 + Text("Clear Order")
  74 + }
  75 + Button(
  76 + onClick = onBack,
  77 + modifier = Modifier.fillMaxWidth()
  78 + ) {
  79 + Text("Back to Menu")
  80 + }
  81 + Button(
  82 + onClick = {
  83 + val orderDetails = selectedItems.joinToString("\n") { item ->
  84 + "${item.name} x${item.quantity} - ${
  85 + NumberFormat.getCurrencyInstance().format(item.price * item.quantity)
  86 + }"
  87 + }
  88 + val summary = "Order Summary:\n$orderDetails\n\nTotal: $totalPrice"
  89 + shareOrder(context, "Your Pizza Order", summary)
  90 + },
  91 + modifier = Modifier.fillMaxWidth()
  92 + ) {
  93 + Text("Share Order")
  94 + }
  95 + Button(
  96 + onClick = onPlace,
  97 + modifier = Modifier.fillMaxWidth(),
  98 + colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary)
  99 + ) {
  100 + Text("Place Order")
  101 + }
  102 + }
  103 +
  104 + if (showDialog) {
  105 + AlertDialog(
  106 + onDismissRequest = { showDialog = false },
  107 + title = { Text("Confirm Clear Order") },
  108 + text = { Text("Are you sure you want to clear your order? This action cannot be undone.") },
  109 + confirmButton = {
  110 + Button(
  111 + onClick = {
  112 + viewModel.clearOrder()
  113 + showDialog = false
  114 + }
  115 + ) {
  116 + Text("Yes, Clear Order")
  117 + }
  118 + },
  119 + dismissButton = {
  120 + OutlinedButton(onClick = { showDialog = false }) {
  121 + Text("Cancel")
  122 + }
  123 + }
  124 + )
  125 + }
  126 + }
  127 +}
  128 +
  129 +fun shareOrder(context: Context, subject: String, summary: String) {
  130 + val intent = Intent(Intent.ACTION_SEND).apply {
  131 + type = "text/plain"
  132 + putExtra(Intent.EXTRA_SUBJECT, subject)
  133 + putExtra(Intent.EXTRA_TEXT, summary)
  134 + }
  135 +
  136 + context.startActivity(
  137 + Intent.createChooser(
  138 + intent,
  139 + context.getString(R.string.new_pizza_order)
  140 + )
  141 + )
  142 +}
  1 +package com.example.pizzaorder.ui.components
  2 +
  3 +import androidx.compose.material3.MaterialTheme
  4 +import androidx.compose.material3.Text
  5 +import androidx.compose.runtime.Composable
  6 +import androidx.compose.ui.Modifier
  7 +import androidx.compose.ui.res.stringResource
  8 +import com.example.pizzaorder.R
  9 +
  10 +
  11 +@Composable
  12 +fun FormattedPriceLabel(subtotal: String, modifier: Modifier = Modifier) {
  13 + Text(
  14 + text = stringResource(R.string.subtotal_price, subtotal),
  15 + modifier = modifier,
  16 + style = MaterialTheme.typography.headlineSmall
  17 + )
  18 +}
  1 +package com.example.pizzaorder.ui.theme
  2 +
  3 +import androidx.compose.ui.graphics.Color
  4 +
  5 +val md_theme_light_primary = Color(0xFF984062)
  6 +val md_theme_light_onPrimary = Color(0xFFFFFFFF)
  7 +val md_theme_light_primaryContainer = Color(0xFFFFD9E2)
  8 +val md_theme_light_onPrimaryContainer = Color(0xFF3E001E)
  9 +val md_theme_light_secondary = Color(0xFF74565F)
  10 +val md_theme_light_onSecondary = Color(0xFFFFFFFF)
  11 +val md_theme_light_secondaryContainer = Color(0xFFFFD9E2)
  12 +val md_theme_light_onSecondaryContainer = Color(0xFF2B151C)
  13 +val md_theme_light_tertiary = Color(0xFF7C5635)
  14 +val md_theme_light_onTertiary = Color(0xFFFFFFFF)
  15 +val md_theme_light_tertiaryContainer = Color(0xFFFFDCC2)
  16 +val md_theme_light_onTertiaryContainer = Color(0xFF2E1500)
  17 +val md_theme_light_error = Color(0xFFBA1A1A)
  18 +val md_theme_light_errorContainer = Color(0xFFFFDAD6)
  19 +val md_theme_light_onError = Color(0xFFFFFFFF)
  20 +val md_theme_light_onErrorContainer = Color(0xFF410002)
  21 +val md_theme_light_background = Color(0xFFFFFBFF)
  22 +val md_theme_light_onBackground = Color(0xFF201A1B)
  23 +val md_theme_light_surface = Color(0xFFFFFBFF)
  24 +val md_theme_light_onSurface = Color(0xFF201A1B)
  25 +val md_theme_light_surfaceVariant = Color(0xFFF2DDE2)
  26 +val md_theme_light_onSurfaceVariant = Color(0xFF514347)
  27 +val md_theme_light_outline = Color(0xFF837377)
  28 +val md_theme_light_inverseOnSurface = Color(0xFFFAEEEF)
  29 +val md_theme_light_inverseSurface = Color(0xFF352F30)
  30 +val md_theme_light_inversePrimary = Color(0xFFFFB0C9)
  31 +val md_theme_light_surfaceTint = Color(0xFF984062)
  32 +val md_theme_light_outlineVariant = Color(0xFFD5C2C6)
  33 +val md_theme_light_scrim = Color(0xFF000000)
  34 +
  35 +val md_theme_dark_primary = Color(0xFFFFB0C9)
  36 +val md_theme_dark_onPrimary = Color(0xFF5E1133)
  37 +val md_theme_dark_primaryContainer = Color(0xFF7B294A)
  38 +val md_theme_dark_onPrimaryContainer = Color(0xFFFFD9E2)
  39 +val md_theme_dark_secondary = Color(0xFFE2BDC7)
  40 +val md_theme_dark_onSecondary = Color(0xFF422931)
  41 +val md_theme_dark_secondaryContainer = Color(0xFF5A3F47)
  42 +val md_theme_dark_onSecondaryContainer = Color(0xFFFFD9E2)
  43 +val md_theme_dark_tertiary = Color(0xFFEFBD94)
  44 +val md_theme_dark_onTertiary = Color(0xFF48290C)
  45 +val md_theme_dark_tertiaryContainer = Color(0xFF623F20)
  46 +val md_theme_dark_onTertiaryContainer = Color(0xFFFFDCC2)
  47 +val md_theme_dark_error = Color(0xFFFFB4AB)
  48 +val md_theme_dark_errorContainer = Color(0xFF93000A)
  49 +val md_theme_dark_onError = Color(0xFF690005)
  50 +val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
  51 +val md_theme_dark_background = Color(0xFF201A1B)
  52 +val md_theme_dark_onBackground = Color(0xFFEBE0E1)
  53 +val md_theme_dark_surface = Color(0xFF201A1B)
  54 +val md_theme_dark_onSurface = Color(0xFFEBE0E1)
  55 +val md_theme_dark_surfaceVariant = Color(0xFF514347)
  56 +val md_theme_dark_onSurfaceVariant = Color(0xFFD5C2C6)
  57 +val md_theme_dark_outline = Color(0xFF9E8C90)
  58 +val md_theme_dark_inverseOnSurface = Color(0xFF201A1B)
  59 +val md_theme_dark_inverseSurface = Color(0xFFEBE0E1)
  60 +val md_theme_dark_inversePrimary = Color(0xFF984062)
  61 +val md_theme_dark_surfaceTint = Color(0xFFFFB0C9)
  62 +val md_theme_dark_outlineVariant = Color(0xFF514347)
  63 +val md_theme_dark_scrim = Color(0xFF000000)
  1 +package com.example.pizzaorder.ui.theme
  2 +
  3 +import android.app.Activity
  4 +import android.os.Build
  5 +import androidx.compose.foundation.isSystemInDarkTheme
  6 +import androidx.compose.material3.MaterialTheme
  7 +import androidx.compose.material3.darkColorScheme
  8 +import androidx.compose.material3.dynamicDarkColorScheme
  9 +import androidx.compose.material3.dynamicLightColorScheme
  10 +import androidx.compose.material3.lightColorScheme
  11 +import androidx.compose.runtime.Composable
  12 +import androidx.compose.runtime.SideEffect
  13 +import androidx.compose.ui.graphics.toArgb
  14 +import androidx.compose.ui.platform.LocalContext
  15 +import androidx.compose.ui.platform.LocalView
  16 +import androidx.core.view.WindowCompat
  17 +
  18 +private val LightColors = lightColorScheme(
  19 + primary = md_theme_light_primary,
  20 + onPrimary = md_theme_light_onPrimary,
  21 + primaryContainer = md_theme_light_primaryContainer,
  22 + onPrimaryContainer = md_theme_light_onPrimaryContainer,
  23 + secondary = md_theme_light_secondary,
  24 + onSecondary = md_theme_light_onSecondary,
  25 + secondaryContainer = md_theme_light_secondaryContainer,
  26 + onSecondaryContainer = md_theme_light_onSecondaryContainer,
  27 + tertiary = md_theme_light_tertiary,
  28 + onTertiary = md_theme_light_onTertiary,
  29 + tertiaryContainer = md_theme_light_tertiaryContainer,
  30 + onTertiaryContainer = md_theme_light_onTertiaryContainer,
  31 + error = md_theme_light_error,
  32 + errorContainer = md_theme_light_errorContainer,
  33 + onError = md_theme_light_onError,
  34 + onErrorContainer = md_theme_light_onErrorContainer,
  35 + background = md_theme_light_background,
  36 + onBackground = md_theme_light_onBackground,
  37 + surface = md_theme_light_surface,
  38 + onSurface = md_theme_light_onSurface,
  39 + surfaceVariant = md_theme_light_surfaceVariant,
  40 + onSurfaceVariant = md_theme_light_onSurfaceVariant,
  41 + outline = md_theme_light_outline,
  42 + inverseOnSurface = md_theme_light_inverseOnSurface,
  43 + inverseSurface = md_theme_light_inverseSurface,
  44 + inversePrimary = md_theme_light_inversePrimary,
  45 + surfaceTint = md_theme_light_surfaceTint,
  46 + outlineVariant = md_theme_light_outlineVariant,
  47 + scrim = md_theme_light_scrim,
  48 +)
  49 +
  50 +private val DarkColors = darkColorScheme(
  51 + primary = md_theme_dark_primary,
  52 + onPrimary = md_theme_dark_onPrimary,
  53 + primaryContainer = md_theme_dark_primaryContainer,
  54 + onPrimaryContainer = md_theme_dark_onPrimaryContainer,
  55 + secondary = md_theme_dark_secondary,
  56 + onSecondary = md_theme_dark_onSecondary,
  57 + secondaryContainer = md_theme_dark_secondaryContainer,
  58 + onSecondaryContainer = md_theme_dark_onSecondaryContainer,
  59 + tertiary = md_theme_dark_tertiary,
  60 + onTertiary = md_theme_dark_onTertiary,
  61 + tertiaryContainer = md_theme_dark_tertiaryContainer,
  62 + onTertiaryContainer = md_theme_dark_onTertiaryContainer,
  63 + error = md_theme_dark_error,
  64 + errorContainer = md_theme_dark_errorContainer,
  65 + onError = md_theme_dark_onError,
  66 + onErrorContainer = md_theme_dark_onErrorContainer,
  67 + background = md_theme_dark_background,
  68 + onBackground = md_theme_dark_onBackground,
  69 + surface = md_theme_dark_surface,
  70 + onSurface = md_theme_dark_onSurface,
  71 + surfaceVariant = md_theme_dark_surfaceVariant,
  72 + onSurfaceVariant = md_theme_dark_onSurfaceVariant,
  73 + outline = md_theme_dark_outline,
  74 + inverseOnSurface = md_theme_dark_inverseOnSurface,
  75 + inverseSurface = md_theme_dark_inverseSurface,
  76 + inversePrimary = md_theme_dark_inversePrimary,
  77 + surfaceTint = md_theme_dark_surfaceTint,
  78 + outlineVariant = md_theme_dark_outlineVariant,
  79 + scrim = md_theme_dark_scrim,
  80 +)
  81 +
  82 +@Composable
  83 +fun PizzaTheme(
  84 + darkTheme: Boolean = isSystemInDarkTheme(),
  85 + // Dynamic color is available on Android 12+ but turned off for training purposes
  86 + dynamicColor: Boolean = false,
  87 + content: @Composable () -> Unit
  88 +) {
  89 + val colorScheme = when {
  90 + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
  91 + val context = LocalContext.current
  92 + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
  93 + }
  94 +
  95 + darkTheme -> DarkColors
  96 + else -> LightColors
  97 + }
  98 + val view = LocalView.current
  99 + if (!view.isInEditMode) {
  100 + SideEffect {
  101 + val window = (view.context as Activity).window
  102 + window.statusBarColor = colorScheme.primary.toArgb()
  103 + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
  104 + }
  105 + }
  106 +
  107 + MaterialTheme(
  108 + colorScheme = colorScheme,
  109 + typography = Typography,
  110 + content = content
  111 + )
  112 +}
  1 +package com.example.pizzaorder.ui.theme
  2 +
  3 +import androidx.compose.material3.Typography
  4 +import androidx.compose.ui.text.TextStyle
  5 +import androidx.compose.ui.text.font.FontFamily
  6 +import androidx.compose.ui.text.font.FontWeight
  7 +import androidx.compose.ui.unit.sp
  8 +
  9 +
  10 +val Typography = Typography(
  11 + bodyLarge = TextStyle(
  12 + fontFamily = FontFamily.Default,
  13 + fontWeight = FontWeight.Normal,
  14 + fontSize = 16.sp,
  15 + lineHeight = 24.sp,
  16 + letterSpacing = 0.5.sp
  17 + )
  18 +)
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<vector xmlns:android="http://schemas.android.com/apk/res/android"
  3 + android:width="108dp"
  4 + android:height="108dp"
  5 + android:viewportWidth="108"
  6 + android:viewportHeight="108">
  7 + <path
  8 + android:fillColor="#3DDC84"
  9 + android:pathData="M0,0h108v108h-108z" />
  10 + <path
  11 + android:fillColor="#00000000"
  12 + android:pathData="M9,0L9,108"
  13 + android:strokeWidth="0.8"
  14 + android:strokeColor="#33FFFFFF" />
  15 + <path
  16 + android:fillColor="#00000000"
  17 + android:pathData="M19,0L19,108"
  18 + android:strokeWidth="0.8"
  19 + android:strokeColor="#33FFFFFF" />
  20 + <path
  21 + android:fillColor="#00000000"
  22 + android:pathData="M29,0L29,108"
  23 + android:strokeWidth="0.8"
  24 + android:strokeColor="#33FFFFFF" />
  25 + <path
  26 + android:fillColor="#00000000"
  27 + android:pathData="M39,0L39,108"
  28 + android:strokeWidth="0.8"
  29 + android:strokeColor="#33FFFFFF" />
  30 + <path
  31 + android:fillColor="#00000000"
  32 + android:pathData="M49,0L49,108"
  33 + android:strokeWidth="0.8"
  34 + android:strokeColor="#33FFFFFF" />
  35 + <path
  36 + android:fillColor="#00000000"
  37 + android:pathData="M59,0L59,108"
  38 + android:strokeWidth="0.8"
  39 + android:strokeColor="#33FFFFFF" />
  40 + <path
  41 + android:fillColor="#00000000"
  42 + android:pathData="M69,0L69,108"
  43 + android:strokeWidth="0.8"
  44 + android:strokeColor="#33FFFFFF" />
  45 + <path
  46 + android:fillColor="#00000000"
  47 + android:pathData="M79,0L79,108"
  48 + android:strokeWidth="0.8"
  49 + android:strokeColor="#33FFFFFF" />
  50 + <path
  51 + android:fillColor="#00000000"
  52 + android:pathData="M89,0L89,108"
  53 + android:strokeWidth="0.8"
  54 + android:strokeColor="#33FFFFFF" />
  55 + <path
  56 + android:fillColor="#00000000"
  57 + android:pathData="M99,0L99,108"
  58 + android:strokeWidth="0.8"
  59 + android:strokeColor="#33FFFFFF" />
  60 + <path
  61 + android:fillColor="#00000000"
  62 + android:pathData="M0,9L108,9"
  63 + android:strokeWidth="0.8"
  64 + android:strokeColor="#33FFFFFF" />
  65 + <path
  66 + android:fillColor="#00000000"
  67 + android:pathData="M0,19L108,19"
  68 + android:strokeWidth="0.8"
  69 + android:strokeColor="#33FFFFFF" />
  70 + <path
  71 + android:fillColor="#00000000"
  72 + android:pathData="M0,29L108,29"
  73 + android:strokeWidth="0.8"
  74 + android:strokeColor="#33FFFFFF" />
  75 + <path
  76 + android:fillColor="#00000000"
  77 + android:pathData="M0,39L108,39"
  78 + android:strokeWidth="0.8"
  79 + android:strokeColor="#33FFFFFF" />
  80 + <path
  81 + android:fillColor="#00000000"
  82 + android:pathData="M0,49L108,49"
  83 + android:strokeWidth="0.8"
  84 + android:strokeColor="#33FFFFFF" />
  85 + <path
  86 + android:fillColor="#00000000"
  87 + android:pathData="M0,59L108,59"
  88 + android:strokeWidth="0.8"
  89 + android:strokeColor="#33FFFFFF" />
  90 + <path
  91 + android:fillColor="#00000000"
  92 + android:pathData="M0,69L108,69"
  93 + android:strokeWidth="0.8"
  94 + android:strokeColor="#33FFFFFF" />
  95 + <path
  96 + android:fillColor="#00000000"
  97 + android:pathData="M0,79L108,79"
  98 + android:strokeWidth="0.8"
  99 + android:strokeColor="#33FFFFFF" />
  100 + <path
  101 + android:fillColor="#00000000"
  102 + android:pathData="M0,89L108,89"
  103 + android:strokeWidth="0.8"
  104 + android:strokeColor="#33FFFFFF" />
  105 + <path
  106 + android:fillColor="#00000000"
  107 + android:pathData="M0,99L108,99"
  108 + android:strokeWidth="0.8"
  109 + android:strokeColor="#33FFFFFF" />
  110 + <path
  111 + android:fillColor="#00000000"
  112 + android:pathData="M19,29L89,29"
  113 + android:strokeWidth="0.8"
  114 + android:strokeColor="#33FFFFFF" />
  115 + <path
  116 + android:fillColor="#00000000"
  117 + android:pathData="M19,39L89,39"
  118 + android:strokeWidth="0.8"
  119 + android:strokeColor="#33FFFFFF" />
  120 + <path
  121 + android:fillColor="#00000000"
  122 + android:pathData="M19,49L89,49"
  123 + android:strokeWidth="0.8"
  124 + android:strokeColor="#33FFFFFF" />
  125 + <path
  126 + android:fillColor="#00000000"
  127 + android:pathData="M19,59L89,59"
  128 + android:strokeWidth="0.8"
  129 + android:strokeColor="#33FFFFFF" />
  130 + <path
  131 + android:fillColor="#00000000"
  132 + android:pathData="M19,69L89,69"
  133 + android:strokeWidth="0.8"
  134 + android:strokeColor="#33FFFFFF" />
  135 + <path
  136 + android:fillColor="#00000000"
  137 + android:pathData="M19,79L89,79"
  138 + android:strokeWidth="0.8"
  139 + android:strokeColor="#33FFFFFF" />
  140 + <path
  141 + android:fillColor="#00000000"
  142 + android:pathData="M29,19L29,89"
  143 + android:strokeWidth="0.8"
  144 + android:strokeColor="#33FFFFFF" />
  145 + <path
  146 + android:fillColor="#00000000"
  147 + android:pathData="M39,19L39,89"
  148 + android:strokeWidth="0.8"
  149 + android:strokeColor="#33FFFFFF" />
  150 + <path
  151 + android:fillColor="#00000000"
  152 + android:pathData="M49,19L49,89"
  153 + android:strokeWidth="0.8"
  154 + android:strokeColor="#33FFFFFF" />
  155 + <path
  156 + android:fillColor="#00000000"
  157 + android:pathData="M59,19L59,89"
  158 + android:strokeWidth="0.8"
  159 + android:strokeColor="#33FFFFFF" />
  160 + <path
  161 + android:fillColor="#00000000"
  162 + android:pathData="M69,19L69,89"
  163 + android:strokeWidth="0.8"
  164 + android:strokeColor="#33FFFFFF" />
  165 + <path
  166 + android:fillColor="#00000000"
  167 + android:pathData="M79,19L79,89"
  168 + android:strokeWidth="0.8"
  169 + android:strokeColor="#33FFFFFF" />
  170 +</vector>
  1 +<vector xmlns:android="http://schemas.android.com/apk/res/android"
  2 + xmlns:aapt="http://schemas.android.com/aapt"
  3 + android:width="108dp"
  4 + android:height="108dp"
  5 + android:viewportWidth="108"
  6 + android:viewportHeight="108">
  7 + <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
  8 + <aapt:attr name="android:fillColor">
  9 + <gradient
  10 + android:endX="85.84757"
  11 + android:endY="92.4963"
  12 + android:startX="42.9492"
  13 + android:startY="49.59793"
  14 + android:type="linear">
  15 + <item
  16 + android:color="#44000000"
  17 + android:offset="0.0" />
  18 + <item
  19 + android:color="#00000000"
  20 + android:offset="1.0" />
  21 + </gradient>
  22 + </aapt:attr>
  23 + </path>
  24 + <path
  25 + android:fillColor="#FFFFFF"
  26 + android:fillType="nonZero"
  27 + android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
  28 + android:strokeWidth="1"
  29 + android:strokeColor="#00000000" />
  30 +</vector>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<vector android:height="70dp" android:viewportHeight="183.71"
  3 + android:viewportWidth="208.15" android:width="138.96909dp" xmlns:android="http://schemas.android.com/apk/res/android">
  4 + <path android:fillColor="#ff8e00" android:pathData="M20.24 47.26s-5.48 3.45-6.11 6.89c-.63 3.45.63 7.52 2.35 10.18s3.76 4.86 6.27 5.8s4.7.78 4.7.78s5.8 6.58 16.13 15.51S67.08 106 81.96 114.3s20.21 10.34 24.28 10.34s3.92-6.11 3.45-7.99s-26.63-31.01-26.63-31.01L20.24 47.26z"/>
  5 + <path android:fillColor="#f5b03e" android:pathData="M31.21 62.46l-3.92-4.23s-4.07-7.68-7.83-7.68s-5.33 3.6-5.33 3.6s-.47-3.92 4.23-11.43s10.65-13.47 15.98-17.23s11.9-8.15 16.29-10.65S64.57 9.2 70.06 7.32c5.48-1.88 17.39-4.23 22.87-3.13c5.48 1.1 7.83 4.86 7.83 8.77s-.94 6.58-1.72 7.36s-5.95 5.17-5.95 5.17L31.21 62.46z"/>
  6 + <path android:fillColor="#ffcc8a" android:pathData="M42.2 45.95l-9.71 6.27l-4.07 7.99s.78 2.66 2.04 4.07c1.25 1.41 11.74 11.46 19.25 17.88c5.86 5.01 18.35 15.64 18.35 15.64s.51 5.34 1.1 9.09c.47 2.98.5 7.95 3.64 7.81c3.96-.18 1.68-8.2 4.82-8.12c6.27.16.05 17.12 6.79 17.03c5.37-.07 1.96-9.34 4.65-10.92c1.46-.86 4.36 2.79 9.09 4.86c5.84 2.55 9.4 4.48 11.28 3.6c3.97-1.86-4.4-45.23-5.34-52.59c-.94-7.36-5.62-45.16-5.94-46.41s-6.74-1.41-6.74-1.41l-9.87 3.45l-14.1 1.88l-16.6 9.87l-8.64 10.01z"/>
  7 + <path android:fillColor="#cb6c22" android:pathData="M39.75 44.38c-3.08 1.74-7.05 2.71-10.4 8.23c-2.79 4.6-3.53 9.31-1.54 9.67c1.99.36 3.5-6.58 6.15-9.22c4.25-4.25 7.69-4.7 10.13-6.96s5.11-8.4 15.28-13.83c11.85-6.33 18.93-4.66 21.7-5.7c3.62-1.36 4.6-3.58 9.13-4.52c4.79-.99 8.12.92 8.12.92s1.09-2.53-.36-3.71c-1.45-1.18-4.12-2.1-8.58-1.19c-4.88.99-8.5 4.25-9.49 4.34s-11.12-.45-23.15 6.42s-14.28 14.01-16.99 15.55z"/>
  8 + <path android:fillColor="#db0d27" android:pathData="M53.58 55.32L37.4 58.85s-.25 3.07-.09 3.98c.54 3.07 4.61 7.96 7.05 8.77s7.41.9 9.04.18c1.63-.72 6.51-4.25 7.14-6.15c.63-1.9.46-9.85-.8-11.12c-1.26-1.26-6.16.81-6.16.81z"/>
  9 + <path android:fillColor="#ed6d30" android:pathData="M42.19 50.26c-1.73 1.34-5.06 5.88-4.79 9.13c.27 3.26 5.88 8.95 7.41 9.49s6.51.63 7.78.27s6.15-3.98 6.87-5.24c.72-1.27 1.36-8.32.18-9.58s-4.7-4.97-7.5-5.79c-2.81-.81-8.32.45-9.95 1.72z"/>
  10 + <path android:fillColor="#db0d27" android:pathData="M83.6 65.45s-14.32-1.03-14.5-.13s-.51 4.38.4 7.18c.64 1.99 2.17 5.43 6.87 7.41s9.22-.18 10.4-1.09c2.21-1.7 3.62-3.8 3.98-5.06c.36-1.26-7.15-8.31-7.15-8.31z" />
  11 + <path android:fillColor="#ed6d30" android:pathData="M76.64 57.94c-2.21.8-7.5 4.07-7.6 7.69c-.09 3.62 2.53 8.05 3.89 9.04s5.88 3.62 9.22 3.44c3.35-.18 7.96-2.89 8.59-4.34c.63-1.45.9-5.7.63-7.87s-4.97-7.05-7.32-7.78c-2.35-.72-5.42-.9-7.41-.18z"/>
  12 + <path android:fillColor="#db0d27" android:pathData="M76.1 91.76s-13.11-3.62-13.29-3.35c-.18.27-1.99 2.53-1.54 3.62c.45 1.09 5.06 4.79 6.96 6.42c1.9 1.63 7.64 5 8.32 4.88c1.63-.27 2.89-2.89 2.89-2.89l-3.34-8.68z"/>
  13 + <path android:fillColor="#ed6d30" android:pathData="M77.27 86.24c-3.2-2.35-7.87-2.17-10.4-.99c-2.53 1.18-4.07 2.71-4.34 3.89c-.27 1.18 1.82 3.45 2.64 4.08c.81.63 3.27 2.49 3.27 2.49s3.65 2.86 5 3.9c1.88 1.45 4.24 2.27 4.87 2.36c.63.09 3.57-3.71 3.03-8.78c-.28-2.59-1.38-4.97-4.07-6.95z"/>
  14 + <path android:fillColor="#db0d27" android:pathData="M100.06 79.01l-4.88-.18s-1.99 3.71-.63 7.87c1.11 3.4 3.44 5.43 7.32 6.51c3.89 1.09 6.06.7 6.06.7l.06-2.73l-7.93-12.17z"/>
  15 + <path android:fillColor="#ed6d30" android:pathData="M104.76 72.77s-6.02-.71-9.13 4.88c-2.38 4.29-.72 7.87 1.18 9.95c1.9 2.08 4.79 3.44 6.96 3.62s4.27.01 4.27.01s-.84-5.55-1.66-10.19c-.5-2.78-1.62-8.27-1.62-8.27z"/>
  16 + <path android:fillColor="#db0d27" android:pathData="M87.22 33.62s-11.66.36-12.39 1.54s-.72 6.42-.36 8.5s3.53 7.14 9.86 7.23c6.33.09 8.56-1.49 11.02-6.27c2.46-4.78-.1-10.13-.1-10.13l-8.03-.87z"/>
  17 + <path android:fillColor="#ed6d30" android:pathData="M87.31 28.28c-2.53-.49-6.06.54-7.78 1.72c-1.72 1.18-4.52 3.62-4.7 5.43c-.18 1.81 1.45 7.05 2.08 8.05c.63.99 3.25 3.68 4.07 4.07c1.9.9 7.14.45 8.68-.09s5.79-3.98 6.24-5.79s.99-4.88-1.09-8.59s-5.15-4.34-7.5-4.8z"/>
  18 + <path android:fillColor="#db0d27" android:pathData="M103.78 104.17l-10.41-.45s-1.4 2.81-.98 5.27c.34 2.04 2.03 4.82 5.06 5.99c1.72.66 6.22.23 7.32-.52c2.22-1.52 2.93-4.28 2.86-5.7c-.03-.74-3.85-4.59-3.85-4.59z" />
  19 + <path android:fillColor="#ed6d30" android:pathData="M101.51 99.75c-2.7-.41-5.81 1.05-7.15 2.44c-1.34 1.39-1.61 3.13-1.1 5.23c.93 3.84 3.39 4.93 4.53 5.52c1.69.87 6.33.7 7.79-.41c1.45-1.1 2.55-2.98 2.21-5.87c-.35-2.9-1.63-6.21-6.28-6.91z"/>
  20 + <path android:fillColor="#fcc12b" android:pathData="M36 31.03c.09 2.16 3.87 1.79 5.36 1.64c1.19-.12 4.17-.37 4.17-2.31s-2.6-1.93-4.54-1.86c-1.87.07-5.07.82-4.99 2.53z"/>
  21 + <path android:fillColor="#fcc12b" android:pathData="M56.31 18.31c0 1.42 1.56 1.56 2.53 1.64c.97.07 2.23-.3 2.31-1.41c.07-1.12-.89-1.79-2.31-1.86c-1.49-.09-2.53.43-2.53 1.63z"/>
  22 + <path android:fillColor="#fcc12b" android:pathData="M65.61 21.73c1.43 1.55 3.57-.52 4.32-1.49c.74-.97.89-2.46.07-3.2c-.82-.74-2.38.07-3.42 1.04s-1.86 2.68-.97 3.65z"/>
  23 + <path android:fillColor="#fcc12b" android:pathData="M81.76 13.84c1.74 1.97 4.61-1.34 5.8-2.46c1.19-1.12 2.16-2.68 1.04-3.94c-1.12-1.26-3.65.52-4.61 1.64c-.97 1.11-3.35 3.5-2.23 4.76z"/>
  24 + <path android:fillColor="#fcc12b" android:pathData="M26.92 47.25c1.69.4 2.24-1.6 2.53-3.13c.3-1.56.3-3.05-.97-3.27c-1.44-.25-2.23 1.19-2.46 2.6c-.19 1.27-.66 3.43.9 3.8z"/>
  25 +</vector>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <background android:drawable="@drawable/ic_launcher_background" />
  4 + <foreground android:drawable="@drawable/ic_launcher_foreground" />
  5 + <monochrome android:drawable="@drawable/ic_launcher_foreground" />
  6 +</adaptive-icon>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <background android:drawable="@drawable/ic_launcher_background" />
  4 + <foreground android:drawable="@drawable/ic_launcher_foreground" />
  5 + <monochrome android:drawable="@drawable/ic_launcher_foreground" />
  6 +</adaptive-icon>
No preview for this file type
No preview for this file type
No preview for this file type
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <string name="app_name">Cupcake</string>
  4 + <string name="order_pizza">Comandă Pizza</string>
  5 + <string name="one_pizza">O pizza</string>
  6 + <string name="two_pizzas">Două pizza</string>
  7 + <string name="three_pizzas">Trei pizza</string>
  8 + <string name="cancel">Anulare</string>
  9 + <string name="next">Următorul</string>
  10 + <string name="choose_pickup_date">Alege data livrării</string>
  11 + <string name="order_summary">Rezumatul comenzii</string>
  12 + <string name="send">Trimite</string>
  13 + <string name="quantity">Cantitate</string>
  14 + <string name="pizza_type">Tipul de pizza</string>
  15 + <string name="pickup_date">Data ridicării comenzii</string>
  16 + <string name="new_pizza_order">Plasează o nouă comandă</string>
  17 + <string name="order_details">Cantitate: %1$s Tip: %2$s Data ridicării comenzii: %3$s Total: %4$s Vă multumim!</string>
  18 + <string name="login_user_field">Nume de utilizator</string>
  19 + <string name="login_passwd_field">Parolă</string>
  20 + <string name="error_message">Nume de utilizator sau parola invalide!</string>
  21 + <string name="back_button">Inapoi</string>
  22 +</resources>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <color name="purple_200">#FFBB86FC</color>
  4 + <color name="purple_500">#FF6200EE</color>
  5 + <color name="purple_700">#FF3700B3</color>
  6 + <color name="teal_200">#FF03DAC5</color>
  7 + <color name="teal_700">#FF018786</color>
  8 + <color name="black">#FF000000</color>
  9 + <color name="white">#FFFFFFFF</color>
  10 +</resources>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +
  3 +<resources>
  4 + <dimen name="padding_small">8dp</dimen>
  5 + <dimen name="padding_medium">16dp</dimen>
  6 + <dimen name="thickness_divider">1dp</dimen>
  7 +</resources>
  1 +
  2 +<resources>
  3 +<string name="app_name">Pizza</string>
  4 +<string name="order_pizza">Pizza</string>
  5 +<string name="start_order" translatable="false">Start order</string>
  6 +<string name="login" translatable="false">Login</string>
  7 +<string name="signup" translatable="false"> Sign Up</string>
  8 +<string name="forgot_password" translatable="false"> I forgot my password</string>
  9 +<string name="forgot_email_field" translatable="false"> Email </string>
  10 +<string name="forgot_password_button" translatable="false"> Forgot Button </string>
  11 +<string name="signup_button" translatable="false"> Sign Up </string>
  12 +<string name="signup_email_field" translatable="false"> Email </string>
  13 +<string name="signup_password_field" translatable="false"> Password </string>
  14 +<string name="signup_confirm_password_field" translatable="false"> Confirm Password </string>
  15 +<string name="one_pizza">One Pizza</string>
  16 +<string name="two_pizzas">Two Pizzas</string>
  17 +<string name="three_pizzas">Three Pizzas</string>
  18 +<string name="choose_pizza_type" translatable="false">Choose Pizza</string>
  19 +<string name="choose_burger_type" translatable="false">Choose Burger</string>
  20 +<string name="pizza_marguerita" translatable="false">Marguerita</string>
  21 +<string name="pizza_quattro_formaggi" translatable="false">Quattro Formaggi</string>
  22 +<string name="pizza_quattro_stagioni" translatable="false">Quattro Stagioni</string>
  23 +<string name="pizza_diavola" translatable="false">Diavola</string>
  24 +<string name="pizza_capriciosa" translatable="false">Capriciosa</string>
  25 +<string name="cancel">Cancel</string>
  26 +<string name="next">Next</string>
  27 +<string name="choose_pickup_date">Choose Pickup Date</string>
  28 +<string name="order_summary">Order Summary</string>
  29 +<string name="order_placed" translatable="false">Order Placed</string>
  30 +<string name="send">Send</string>
  31 +<string name="quantity">Quantity</string>
  32 +<string name="pizza_type">Pizza Type</string>
  33 +<string name="pickup_date">Pickup date</string>
  34 +<string name="subtotal_price" translatable="false">Subtotal %s</string>
  35 +<string name="total_price" translatable="false">Total %s</string>
  36 +<string name="new_pizza_order">New Pizza Order</string>
  37 +<string name="order_details">Quantity: %1$s Type: %2$s Pickup date: %3$s Total: %4$s Thank you!</string>
  38 +<string name="login_user_field">Username</string>
  39 +<string name="login_passwd_field">Password</string>
  40 +<string name="error_message">Invalid username or password!</string>
  41 +<string name="back_button">Back</string>
  42 +<string name="login_button" translatable="false">Login</string>
  43 +<string name="menu_button" translatable="false">Menu</string>
  44 +<string name="home" translatable="false">Home</string>
  45 +<string name="orders" translatable="false">Orders</string>
  46 +<string name="logout" translatable="false">Logout</string>
  47 +<string name="classic_burger" translatable="false">Classic Burger</string>
  48 +<string name="cheeseburger" translatable="false">Cheeseburger</string>
  49 +<string name="veggie_burger" translatable="false">Veggie Burger</string>
  50 +<string name="bacon_burger" translatable="false">Bacon Burger</string>
  51 +<string name="double_burger" translatable="false">Double Burger</string>
  52 +<string name="order_burgers" translatable="false">Burgers</string>
  53 +<string name="back_to_menu" translatable="false">Back to menu</string>
  54 +<string name="view_order_summary" translatable="false">View Summary</string>
  55 +<plurals name="pizzas" translatable="false">
  56 + <item quantity="one">%d pizza</item>
  57 + <item quantity="other">%d pizzas</item>
  58 +</plurals>
  59 +
  60 +</resources>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <style name="Theme.PizzaOrder" parent="android:Theme.Material.Light.NoActionBar" />
  4 +</resources>
  1 +<?xml version="1.0" encoding="utf-8"?><!--
  2 + Sample backup rules file; uncomment and customize as necessary.
  3 + See https://developer.android.com/guide/topics/data/autobackup
  4 + for details.
  5 + Note: This file is ignored for devices older that API 31
  6 + See https://developer.android.com/about/versions/12/backup-restore
  7 +-->
  8 +<full-backup-content>
  9 + <!--
  10 + <include domain="sharedpref" path="."/>
  11 + <exclude domain="sharedpref" path="device.xml"/>
  12 +-->
  13 +</full-backup-content>
  1 +<?xml version="1.0" encoding="utf-8"?><!--
  2 + Sample data extraction rules file; uncomment and customize as necessary.
  3 + See https://developer.android.com/about/versions/12/backup-restore#xml-changes
  4 + for details.
  5 +-->
  6 +<data-extraction-rules>
  7 + <cloud-backup>
  8 + <!-- TODO: Use <include> and <exclude> to control what is backed up.
  9 + <include .../>
  10 + <exclude .../>
  11 + -->
  12 + </cloud-backup>
  13 + <!--
  14 + <device-transfer>
  15 + <include .../>
  16 + <exclude .../>
  17 + </device-transfer>
  18 + -->
  19 +</data-extraction-rules>
  1 +package com.example.pizzaorder
  2 +
  3 +import org.junit.Test
  4 +
  5 +import org.junit.Assert.*
  6 +
  7 +
  8 +class ExampleUnitTest {
  9 + @Test
  10 + fun addition_isCorrect() {
  11 + assertEquals(4, 2 + 2)
  12 + }
  13 +}
  1 +// Top-level build file where you can add configuration options common to all sub-projects/modules.
  2 +plugins {
  3 + alias(libs.plugins.android.application) apply false
  4 + alias(libs.plugins.kotlin.android) apply false
  5 + alias(libs.plugins.kotlin.compose) apply false
  6 + // Add the dependency for the Google services Gradle plugin
  7 + id("com.google.gms.google-services") version "4.4.2" apply false
  8 +}
  1 +# Project-wide Gradle settings.
  2 +# IDE (e.g. Android Studio) users:
  3 +# Gradle settings configured through the IDE *will override*
  4 +# any settings specified in this file.
  5 +# For more details on how to configure your build environment visit
  6 +# http://www.gradle.org/docs/current/userguide/build_environment.html
  7 +# Specifies the JVM arguments used for the daemon process.
  8 +# The setting is particularly useful for tweaking memory settings.
  9 +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
  10 +# When configured, Gradle will run in incubating parallel mode.
  11 +# This option should only be used with decoupled projects. For more details, visit
  12 +# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
  13 +# org.gradle.parallel=true
  14 +# AndroidX package structure to make it clearer which packages are bundled with the
  15 +# Android operating system, and which are packaged with your app's APK
  16 +# https://developer.android.com/topic/libraries/support-library/androidx-rn
  17 +android.useAndroidX=true
  18 +# Kotlin code style for this project: "official" or "obsolete":
  19 +kotlin.code.style=official
  20 +# Enables namespacing of each library's R class so that its R class includes only the
  21 +# resources declared in the library itself and none from the library's dependencies,
  22 +# thereby reducing the size of the R class for that library
  23 +android.nonTransitiveRClass=true
  1 +[versions]
  2 +agp = "8.7.0"
  3 +credentials = "1.5.0-beta01"
  4 +credentialsPlayServicesAuth = "1.3.0"
  5 +credentialsPlayServicesAuthVersion = "1.5.0-beta01"
  6 +firebaseBom = "33.6.0"
  7 +firebaseBomVersion = "33.8.0"
  8 +kotlin = "2.0.0"
  9 +coreKtx = "1.15.0"
  10 +junit = "4.13.2"
  11 +junitVersion = "1.2.1"
  12 +espressoCore = "3.6.1"
  13 +lifecycleRuntimeKtx = "2.8.7"
  14 +activityCompose = "1.9.3"
  15 +composeBom = "2024.04.01"
  16 +navigationRuntimeKtx = "2.8.4"
  17 +navigationCompose = "2.8.4"
  18 +activityKtx = "1.9.3"
  19 +
  20 +[libraries]
  21 +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
  22 +androidx-credentials = { module = "androidx.credentials:credentials", version.ref = "credentials" }
  23 +androidx-credentials-play-services-auth = { module = "androidx.credentials:credentials-play-services-auth", version.ref = "credentialsPlayServicesAuth" }
  24 +androidx-credentials-play-services-auth-v150beta01 = { module = "androidx.credentials:credentials-play-services-auth", version.ref = "credentialsPlayServicesAuthVersion" }
  25 +firebase-analytics = { module = "com.google.firebase:firebase-analytics" }
  26 +firebase-auth = { module = "com.google.firebase:firebase-auth" }
  27 +firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" }
  28 +firebase-bom-v3380 = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBomVersion" }
  29 +firebase-firestore = { module = "com.google.firebase:firebase-firestore" }
  30 +google-firebase-analytics = { module = "com.google.firebase:firebase-analytics" }
  31 +google-firebase-firestore = { module = "com.google.firebase:firebase-firestore" }
  32 +junit = { group = "junit", name = "junit", version.ref = "junit" }
  33 +androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
  34 +androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
  35 +androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
  36 +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
  37 +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
  38 +androidx-ui = { group = "androidx.compose.ui", name = "ui" }
  39 +androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
  40 +androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
  41 +androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
  42 +androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
  43 +androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
  44 +androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
  45 +androidx-navigation-runtime-ktx = { group = "androidx.navigation", name = "navigation-runtime-ktx", version.ref = "navigationRuntimeKtx" }
  46 +androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
  47 +androidx-activity-ktx = { group = "androidx.activity", name = "activity-ktx", version.ref = "activityKtx" }
  48 +
  49 +[plugins]
  50 +android-application = { id = "com.android.application", version.ref = "agp" }
  51 +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
  52 +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
  53 +
No preview for this file type
  1 +#Mon Dec 02 22:14:37 EET 2024
  2 +distributionBase=GRADLE_USER_HOME
  3 +distributionPath=wrapper/dists
  4 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
  5 +zipStoreBase=GRADLE_USER_HOME
  6 +zipStorePath=wrapper/dists
  1 +#!/usr/bin/env sh
  2 +
  3 +#
  4 +# Copyright 2015 the original author or authors.
  5 +#
  6 +# Licensed under the Apache License, Version 2.0 (the "License");
  7 +# you may not use this file except in compliance with the License.
  8 +# You may obtain a copy of the License at
  9 +#
  10 +# https://www.apache.org/licenses/LICENSE-2.0
  11 +#
  12 +# Unless required by applicable law or agreed to in writing, software
  13 +# distributed under the License is distributed on an "AS IS" BASIS,
  14 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15 +# See the License for the specific language governing permissions and
  16 +# limitations under the License.
  17 +#
  18 +
  19 +##############################################################################
  20 +##
  21 +## Gradle start up script for UN*X
  22 +##
  23 +##############################################################################
  24 +
  25 +# Attempt to set APP_HOME
  26 +# Resolve links: $0 may be a link
  27 +PRG="$0"
  28 +# Need this for relative symlinks.
  29 +while [ -h "$PRG" ] ; do
  30 + ls=`ls -ld "$PRG"`
  31 + link=`expr "$ls" : '.*-> \(.*\)$'`
  32 + if expr "$link" : '/.*' > /dev/null; then
  33 + PRG="$link"
  34 + else
  35 + PRG=`dirname "$PRG"`"/$link"
  36 + fi
  37 +done
  38 +SAVED="`pwd`"
  39 +cd "`dirname \"$PRG\"`/" >/dev/null
  40 +APP_HOME="`pwd -P`"
  41 +cd "$SAVED" >/dev/null
  42 +
  43 +APP_NAME="Gradle"
  44 +APP_BASE_NAME=`basename "$0"`
  45 +
  46 +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
  47 +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
  48 +
  49 +# Use the maximum available, or set MAX_FD != -1 to use that value.
  50 +MAX_FD="maximum"
  51 +
  52 +warn () {
  53 + echo "$*"
  54 +}
  55 +
  56 +die () {
  57 + echo
  58 + echo "$*"
  59 + echo
  60 + exit 1
  61 +}
  62 +
  63 +# OS specific support (must be 'true' or 'false').
  64 +cygwin=false
  65 +msys=false
  66 +darwin=false
  67 +nonstop=false
  68 +case "`uname`" in
  69 + CYGWIN* )
  70 + cygwin=true
  71 + ;;
  72 + Darwin* )
  73 + darwin=true
  74 + ;;
  75 + MINGW* )
  76 + msys=true
  77 + ;;
  78 + NONSTOP* )
  79 + nonstop=true
  80 + ;;
  81 +esac
  82 +
  83 +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
  84 +
  85 +
  86 +# Determine the Java command to use to start the JVM.
  87 +if [ -n "$JAVA_HOME" ] ; then
  88 + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
  89 + # IBM's JDK on AIX uses strange locations for the executables
  90 + JAVACMD="$JAVA_HOME/jre/sh/java"
  91 + else
  92 + JAVACMD="$JAVA_HOME/bin/java"
  93 + fi
  94 + if [ ! -x "$JAVACMD" ] ; then
  95 + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
  96 +
  97 +Please set the JAVA_HOME variable in your environment to match the
  98 +location of your Java installation."
  99 + fi
  100 +else
  101 + JAVACMD="java"
  102 + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
  103 +
  104 +Please set the JAVA_HOME variable in your environment to match the
  105 +location of your Java installation."
  106 +fi
  107 +
  108 +# Increase the maximum file descriptors if we can.
  109 +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
  110 + MAX_FD_LIMIT=`ulimit -H -n`
  111 + if [ $? -eq 0 ] ; then
  112 + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
  113 + MAX_FD="$MAX_FD_LIMIT"
  114 + fi
  115 + ulimit -n $MAX_FD
  116 + if [ $? -ne 0 ] ; then
  117 + warn "Could not set maximum file descriptor limit: $MAX_FD"
  118 + fi
  119 + else
  120 + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
  121 + fi
  122 +fi
  123 +
  124 +# For Darwin, add options to specify how the application appears in the dock
  125 +if $darwin; then
  126 + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
  127 +fi
  128 +
  129 +# For Cygwin or MSYS, switch paths to Windows format before running java
  130 +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
  131 + APP_HOME=`cygpath --path --mixed "$APP_HOME"`
  132 + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
  133 +
  134 + JAVACMD=`cygpath --unix "$JAVACMD"`
  135 +
  136 + # We build the pattern for arguments to be converted via cygpath
  137 + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
  138 + SEP=""
  139 + for dir in $ROOTDIRSRAW ; do
  140 + ROOTDIRS="$ROOTDIRS$SEP$dir"
  141 + SEP="|"
  142 + done
  143 + OURCYGPATTERN="(^($ROOTDIRS))"
  144 + # Add a user-defined pattern to the cygpath arguments
  145 + if [ "$GRADLE_CYGPATTERN" != "" ] ; then
  146 + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
  147 + fi
  148 + # Now convert the arguments - kludge to limit ourselves to /bin/sh
  149 + i=0
  150 + for arg in "$@" ; do
  151 + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
  152 + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
  153 +
  154 + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
  155 + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
  156 + else
  157 + eval `echo args$i`="\"$arg\""
  158 + fi
  159 + i=`expr $i + 1`
  160 + done
  161 + case $i in
  162 + 0) set -- ;;
  163 + 1) set -- "$args0" ;;
  164 + 2) set -- "$args0" "$args1" ;;
  165 + 3) set -- "$args0" "$args1" "$args2" ;;
  166 + 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
  167 + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
  168 + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
  169 + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
  170 + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
  171 + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
  172 + esac
  173 +fi
  174 +
  175 +# Escape application args
  176 +save () {
  177 + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
  178 + echo " "
  179 +}
  180 +APP_ARGS=`save "$@"`
  181 +
  182 +# Collect all arguments for the java command, following the shell quoting and substitution rules
  183 +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
  184 +
  185 +exec "$JAVACMD" "$@"
  1 +@rem
  2 +@rem Copyright 2015 the original author or authors.
  3 +@rem
  4 +@rem Licensed under the Apache License, Version 2.0 (the "License");
  5 +@rem you may not use this file except in compliance with the License.
  6 +@rem You may obtain a copy of the License at
  7 +@rem
  8 +@rem https://www.apache.org/licenses/LICENSE-2.0
  9 +@rem
  10 +@rem Unless required by applicable law or agreed to in writing, software
  11 +@rem distributed under the License is distributed on an "AS IS" BASIS,
  12 +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +@rem See the License for the specific language governing permissions and
  14 +@rem limitations under the License.
  15 +@rem
  16 +
  17 +@if "%DEBUG%" == "" @echo off
  18 +@rem ##########################################################################
  19 +@rem
  20 +@rem Gradle startup script for Windows
  21 +@rem
  22 +@rem ##########################################################################
  23 +
  24 +@rem Set local scope for the variables with windows NT shell
  25 +if "%OS%"=="Windows_NT" setlocal
  26 +
  27 +set DIRNAME=%~dp0
  28 +if "%DIRNAME%" == "" set DIRNAME=.
  29 +set APP_BASE_NAME=%~n0
  30 +set APP_HOME=%DIRNAME%
  31 +
  32 +@rem Resolve any "." and ".." in APP_HOME to make it shorter.
  33 +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
  34 +
  35 +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
  36 +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
  37 +
  38 +@rem Find java.exe
  39 +if defined JAVA_HOME goto findJavaFromJavaHome
  40 +
  41 +set JAVA_EXE=java.exe
  42 +%JAVA_EXE% -version >NUL 2>&1
  43 +if "%ERRORLEVEL%" == "0" goto execute
  44 +
  45 +echo.
  46 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
  47 +echo.
  48 +echo Please set the JAVA_HOME variable in your environment to match the
  49 +echo location of your Java installation.
  50 +
  51 +goto fail
  52 +
  53 +:findJavaFromJavaHome
  54 +set JAVA_HOME=%JAVA_HOME:"=%
  55 +set JAVA_EXE=%JAVA_HOME%/bin/java.exe
  56 +
  57 +if exist "%JAVA_EXE%" goto execute
  58 +
  59 +echo.
  60 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
  61 +echo.
  62 +echo Please set the JAVA_HOME variable in your environment to match the
  63 +echo location of your Java installation.
  64 +
  65 +goto fail
  66 +
  67 +:execute
  68 +@rem Setup the command line
  69 +
  70 +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
  71 +
  72 +
  73 +@rem Execute Gradle
  74 +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
  75 +
  76 +:end
  77 +@rem End local scope for the variables with windows NT shell
  78 +if "%ERRORLEVEL%"=="0" goto mainEnd
  79 +
  80 +:fail
  81 +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
  82 +rem the _cmd.exe /c_ return code!
  83 +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
  84 +exit /b 1
  85 +
  86 +:mainEnd
  87 +if "%OS%"=="Windows_NT" endlocal
  88 +
  89 +:omega
  1 +pluginManagement {
  2 + repositories {
  3 + google {
  4 + content {
  5 + includeGroupByRegex("com\\.android.*")
  6 + includeGroupByRegex("com\\.google.*")
  7 + includeGroupByRegex("androidx.*")
  8 + }
  9 + }
  10 + mavenCentral()
  11 + gradlePluginPortal()
  12 + }
  13 +}
  14 +dependencyResolutionManagement {
  15 + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
  16 + repositories {
  17 + google()
  18 + mavenCentral()
  19 + }
  20 +}
  21 +
  22 +rootProject.name = "CupcakeOrder"
  23 +include(":app")
  24 +