├── .gitignore ├── .idea ├── .gitignore ├── compiler.xml ├── deploymentTargetDropDown.xml ├── gradle.xml ├── kotlinc.xml ├── misc.xml └── vcs.xml ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── kelineyt │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── kelineyt │ │ │ ├── KelineApplication.kt │ │ │ ├── activities │ │ │ ├── LoginRegisterActivity.kt │ │ │ └── ShoppingActivity.kt │ │ │ ├── adapters │ │ │ ├── AddressAdapter.kt │ │ │ ├── AllOrdersAdapter.kt │ │ │ ├── BestDealsAdapter.kt │ │ │ ├── BestProductsAdapter.kt │ │ │ ├── BillingProductsAdapter.kt │ │ │ ├── CartProductAdapter.kt │ │ │ ├── ColorsAdapter.kt │ │ │ ├── HomeViewpagerAdapter.kt │ │ │ ├── SizesAdapter.kt │ │ │ ├── SpecialProductsAdapter.kt │ │ │ └── ViewPager2Images.kt │ │ │ ├── data │ │ │ ├── Address.kt │ │ │ ├── CartProduct.kt │ │ │ ├── Category.kt │ │ │ ├── Product.kt │ │ │ ├── User.kt │ │ │ └── order │ │ │ │ ├── Order.kt │ │ │ │ └── OrderStatus.kt │ │ │ ├── di │ │ │ └── AppModule.kt │ │ │ ├── dialog │ │ │ └── ResetPasswordDialog.kt │ │ │ ├── firebase │ │ │ └── FirebaseCommon.kt │ │ │ ├── fragments │ │ │ ├── categories │ │ │ │ ├── AccessoryFragment.kt │ │ │ │ ├── BaseCategoryFragment.kt │ │ │ │ ├── ChairFragment.kt │ │ │ │ ├── CupboardFragment.kt │ │ │ │ ├── FurnitureFragment.kt │ │ │ │ ├── MainCategoryFragment.kt │ │ │ │ └── TableFragment.kt │ │ │ ├── lognRegister │ │ │ │ ├── AccountOptionsFragment.kt │ │ │ │ ├── IntroductionFragment.kt │ │ │ │ ├── LoginFragment.kt │ │ │ │ └── RegisterFragment.kt │ │ │ ├── settings │ │ │ │ ├── AllOrdersFragment.kt │ │ │ │ ├── OrderDetailFragment.kt │ │ │ │ └── UserAccountFragment.kt │ │ │ └── shopping │ │ │ │ ├── AddressFragment.kt │ │ │ │ ├── BillingFragment.kt │ │ │ │ ├── CartFragment.kt │ │ │ │ ├── HomeFragment.kt │ │ │ │ ├── ProductDetailsFragment.kt │ │ │ │ ├── ProfileFragment.kt │ │ │ │ └── SearchFragment.kt │ │ │ ├── helper │ │ │ └── PriceCalculater.kt │ │ │ ├── util │ │ │ ├── Constants.kt │ │ │ ├── HorizontalItemDecoration.kt │ │ │ ├── RegisterValidation.kt │ │ │ ├── Resource.kt │ │ │ ├── ShowHideBottomNavigation.kt │ │ │ ├── ValidationCheck.kt │ │ │ └── VerticalItemDecoration.kt │ │ │ └── viewmodel │ │ │ ├── AddressViewModel.kt │ │ │ ├── AllOrdersViewModel.kt │ │ │ ├── BillingViewModel.kt │ │ │ ├── CartViewModel.kt │ │ │ ├── CategoryViewModel.kt │ │ │ ├── DetailsViewModel.kt │ │ │ ├── IntroductionViewModel.kt │ │ │ ├── LoginViewModel.kt │ │ │ ├── MainCategoryViewModel.kt │ │ │ ├── OrderViewModel.kt │ │ │ ├── ProfileViewModel.kt │ │ │ ├── RegisterViewModel.kt │ │ │ ├── UserAccountViewModel.kt │ │ │ └── factory │ │ │ └── BaseCategoryViewModelFactoryFactory.kt │ └── res │ │ ├── anim │ │ ├── from_bottom.xml │ │ ├── from_left.xml │ │ ├── from_right.xml │ │ ├── to_left.xml │ │ └── to_right.xml │ │ ├── drawable-v24 │ │ ├── blury_background.jpg │ │ ├── ellips.xml │ │ ├── facebook_login.xml │ │ ├── google_login.xml │ │ ├── ic_add.xml │ │ ├── ic_all_orders.xml │ │ ├── ic_arrow.xml │ │ ├── ic_billing.xml │ │ ├── ic_kleine_shape.xml │ │ ├── ic_language.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_location.xml │ │ ├── ic_logout.xml │ │ ├── ic_notification.xml │ │ └── unselected_button_background.xml │ │ ├── drawable │ │ ├── blue_background.xml │ │ ├── bottom_nav_item_background.xml │ │ ├── bottom_navigation_background.xml │ │ ├── empty_box_background.xml │ │ ├── ic_cart.xml │ │ ├── ic_close.xml │ │ ├── ic_edit.xml │ │ ├── ic_empty_box.xml │ │ ├── ic_empty_box_texture.xml │ │ ├── ic_favorite.xml │ │ ├── ic_home.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_microphone.xml │ │ ├── ic_minus.xml │ │ ├── ic_picked.xml │ │ ├── ic_plus.xml │ │ ├── ic_profile.xml │ │ ├── ic_scan.xml │ │ ├── ic_search.xml │ │ ├── ic_texture_left.xml │ │ ├── ic_texture_right.xml │ │ ├── icon_background.xml │ │ ├── search_box_background.xml │ │ ├── settings_items_background.xml │ │ ├── total_box_background.xml │ │ └── white_background.xml │ │ ├── font │ │ ├── poppins.ttf │ │ ├── poppins_light.ttf │ │ ├── poppins_thin.ttf │ │ └── sf_pro_display.OTF │ │ ├── layout │ │ ├── actitivty_login_register.xml │ │ ├── activity_shopping.xml │ │ ├── address_rv_item.xml │ │ ├── best_deals_rv_item.xml │ │ ├── billing_products_rv_item.xml │ │ ├── cart_product_item.xml │ │ ├── color_rv_item.xml │ │ ├── fragment_account_options.xml │ │ ├── fragment_address.xml │ │ ├── fragment_base_category.xml │ │ ├── fragment_billing.xml │ │ ├── fragment_cart.xml │ │ ├── fragment_home.xml │ │ ├── fragment_introdcution.xml │ │ ├── fragment_login.xml │ │ ├── fragment_main_category.xml │ │ ├── fragment_order_detail.xml │ │ ├── fragment_orders.xml │ │ ├── fragment_product_details.xml │ │ ├── fragment_profile.xml │ │ ├── fragment_register.xml │ │ ├── fragment_search.xml │ │ ├── fragment_user_account.xml │ │ ├── order_item.xml │ │ ├── product_rv_item.xml │ │ ├── reset_passowrd_dialog.xml │ │ ├── size_rv_item.xml │ │ ├── special_rv_item.xml │ │ └── viewpager_image_item.xml │ │ ├── menu │ │ └── bottom_navigation_menu.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── navigation │ │ ├── login_register_graph.xml │ │ └── shopping_graph.xml │ │ ├── values-night │ │ └── themes.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ ├── styles.xml │ │ ├── styles │ │ └── styles.xml │ │ └── themes.xml │ └── test │ └── java │ └── com │ └── example │ └── kelineyt │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 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 16 | app/.gitignore 17 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 35 | 36 | 37 | 38 | 39 | 40 | 42 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'org.jetbrains.kotlin.android' 4 | id 'kotlin-parcelize' 5 | id 'androidx.navigation.safeargs.kotlin' 6 | id 'dagger.hilt.android.plugin' 7 | id 'com.google.gms.google-services' 8 | } 9 | 10 | android { 11 | compileSdk 31 12 | 13 | defaultConfig { 14 | applicationId "com.example.kelineyt" 15 | minSdk 21 16 | targetSdk 31 17 | versionCode 1 18 | versionName "1.0" 19 | 20 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 21 | } 22 | 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | kotlinOptions { 34 | jvmTarget = '1.8' 35 | } 36 | 37 | buildFeatures { 38 | viewBinding true 39 | } 40 | 41 | } 42 | 43 | dependencies { 44 | 45 | implementation 'androidx.core:core-ktx:1.7.0' 46 | implementation 'androidx.appcompat:appcompat:1.4.2' 47 | implementation 'com.google.android.material:material:1.6.1' 48 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4' 49 | implementation 'com.google.firebase:firebase-firestore-ktx:24.2.1' 50 | implementation 'com.google.firebase:firebase-storage:20.1.0' 51 | testImplementation 'junit:junit:4.13.2' 52 | androidTestImplementation 'androidx.test.ext:junit:1.1.3' 53 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 54 | 55 | apply plugin :"kotlin-kapt" 56 | 57 | //Navigation component 58 | def nav_version = "2.5.2" 59 | implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" 60 | implementation "androidx.navigation:navigation-ui-ktx:$nav_version" 61 | 62 | //loading button 63 | implementation 'br.com.simplepass:loading-button-android:2.2.0' 64 | 65 | //Glide 66 | implementation 'com.github.bumptech.glide:glide:4.13.0' 67 | 68 | //circular image 69 | implementation 'de.hdodenhof:circleimageview:3.1.0' 70 | 71 | //viewpager2 indicatior 72 | implementation 'io.github.vejei.viewpagerindicator:viewpagerindicator:1.0.0-alpha.1' 73 | 74 | //stepView 75 | implementation 'com.shuhart.stepview:stepview:1.5.1' 76 | 77 | //Android Ktx 78 | implementation 'androidx.navigation:navigation-fragment-ktx:2.4.2' 79 | 80 | //Dagger hilt 81 | implementation "com.google.dagger:hilt-android:2.38.1" 82 | kapt "com.google.dagger:hilt-compiler:2.38.1" 83 | 84 | //Firebase 85 | implementation 'com.google.firebase:firebase-auth:21.0.6' 86 | 87 | //Coroutines with firebase 88 | implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.5.1' 89 | 90 | } -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "990888778498", 4 | "project_id": "kelineyt", 5 | "storage_bucket": "kelineyt.appspot.com" 6 | }, 7 | "client": [ 8 | { 9 | "client_info": { 10 | "mobilesdk_app_id": "1:990888778498:android:a0460aad9a58a6e936c01b", 11 | "android_client_info": { 12 | "package_name": "com.example.kelineyt" 13 | } 14 | }, 15 | "oauth_client": [ 16 | { 17 | "client_id": "990888778498-1ve8t9skpm6fbh56ad12i5vbsm6jkdfg.apps.googleusercontent.com", 18 | "client_type": 3 19 | } 20 | ], 21 | "api_key": [ 22 | { 23 | "current_key": "AIzaSyChqUc6lS7jLQyHyO-foKaB7bAVYvJ6ZtI" 24 | } 25 | ], 26 | "services": { 27 | "appinvite_service": { 28 | "other_platform_oauth_client": [ 29 | { 30 | "client_id": "990888778498-1ve8t9skpm6fbh56ad12i5vbsm6jkdfg.apps.googleusercontent.com", 31 | "client_type": 3 32 | } 33 | ] 34 | } 35 | } 36 | }, 37 | { 38 | "client_info": { 39 | "mobilesdk_app_id": "1:990888778498:android:41e1b96bcd8ae83436c01b", 40 | "android_client_info": { 41 | "package_name": "com.example.productsadder" 42 | } 43 | }, 44 | "oauth_client": [ 45 | { 46 | "client_id": "990888778498-1ve8t9skpm6fbh56ad12i5vbsm6jkdfg.apps.googleusercontent.com", 47 | "client_type": 3 48 | } 49 | ], 50 | "api_key": [ 51 | { 52 | "current_key": "AIzaSyChqUc6lS7jLQyHyO-foKaB7bAVYvJ6ZtI" 53 | } 54 | ], 55 | "services": { 56 | "appinvite_service": { 57 | "other_platform_oauth_client": [ 58 | { 59 | "client_id": "990888778498-1ve8t9skpm6fbh56ad12i5vbsm6jkdfg.apps.googleusercontent.com", 60 | "client_type": 3 61 | } 62 | ] 63 | } 64 | } 65 | } 66 | ], 67 | "configuration_version": "1" 68 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/kelineyt/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt 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 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.example.kelineyt", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/KelineApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt 2 | 3 | import android.app.Application 4 | import dagger.hilt.android.HiltAndroidApp 5 | 6 | @HiltAndroidApp 7 | class KelineApplication: Application() { 8 | 9 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/activities/LoginRegisterActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.activities 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | import com.example.kelineyt.R 6 | import dagger.hilt.android.AndroidEntryPoint 7 | import dagger.hilt.android.HiltAndroidApp 8 | 9 | @AndroidEntryPoint 10 | class LoginRegisterActivity : AppCompatActivity() { 11 | override fun onCreate(savedInstanceState: Bundle?) { 12 | super.onCreate(savedInstanceState) 13 | setContentView(R.layout.actitivty_login_register) 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/activities/ShoppingActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.activities 2 | 3 | import android.os.Bundle 4 | import android.util.Log 5 | import androidx.activity.viewModels 6 | import androidx.appcompat.app.AppCompatActivity 7 | import androidx.lifecycle.lifecycleScope 8 | import androidx.navigation.findNavController 9 | import androidx.navigation.ui.setupWithNavController 10 | import com.example.kelineyt.R 11 | import com.example.kelineyt.databinding.ActivityShoppingBinding 12 | import com.example.kelineyt.util.Resource 13 | import com.example.kelineyt.viewmodel.CartViewModel 14 | import com.google.android.material.bottomnavigation.BottomNavigationView 15 | import dagger.hilt.android.AndroidEntryPoint 16 | import kotlinx.coroutines.flow.collectLatest 17 | 18 | @AndroidEntryPoint 19 | class ShoppingActivity : AppCompatActivity() { 20 | 21 | val binding by lazy { 22 | ActivityShoppingBinding.inflate(layoutInflater) 23 | } 24 | 25 | val viewModel by viewModels() 26 | 27 | override fun onCreate(savedInstanceState: Bundle?) { 28 | super.onCreate(savedInstanceState) 29 | setContentView(binding.root) 30 | 31 | val navController = findNavController(R.id.shoppingHostFragment) 32 | binding.bottomNavigation.setupWithNavController(navController) 33 | 34 | lifecycleScope.launchWhenStarted { 35 | viewModel.cartProducts.collectLatest { 36 | when (it) { 37 | is Resource.Success -> { 38 | val count = it.data?.size ?: 0 39 | val bottomNavigation = findViewById(R.id.bottomNavigation) 40 | bottomNavigation.getOrCreateBadge(R.id.cartFragment).apply { 41 | number = count 42 | backgroundColor = resources.getColor(R.color.g_blue) 43 | } 44 | } 45 | else -> Unit 46 | } 47 | } 48 | } 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/adapters/AddressAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.adapters 2 | 3 | import android.graphics.drawable.ColorDrawable 4 | import android.util.Log 5 | import android.view.LayoutInflater 6 | import android.view.ViewGroup 7 | import androidx.recyclerview.widget.AsyncListDiffer 8 | import androidx.recyclerview.widget.DiffUtil 9 | import androidx.recyclerview.widget.RecyclerView.Adapter 10 | import androidx.recyclerview.widget.RecyclerView.ViewHolder 11 | import com.example.kelineyt.R 12 | import com.example.kelineyt.data.Address 13 | import com.example.kelineyt.databinding.AddressRvItemBinding 14 | 15 | class AddressAdapter : Adapter() { 16 | 17 | inner class AddressViewHolder(val binding: AddressRvItemBinding) : 18 | ViewHolder(binding.root) { 19 | fun bind(address: Address,isSelected: Boolean) { 20 | binding.apply { 21 | buttonAddress.text = address.addressTitle 22 | if (isSelected){ 23 | buttonAddress.background = ColorDrawable(itemView.context.resources.getColor(R.color.g_blue)) 24 | }else{ 25 | buttonAddress.background = ColorDrawable(itemView.context.resources.getColor(R.color.g_white)) 26 | } 27 | } 28 | } 29 | 30 | 31 | } 32 | 33 | private val diffUtil = object : DiffUtil.ItemCallback
() { 34 | override fun areItemsTheSame(oldItem: Address, newItem: Address): Boolean { 35 | return oldItem.addressTitle == newItem.addressTitle && oldItem.fullName == newItem.fullName 36 | } 37 | 38 | override fun areContentsTheSame(oldItem: Address, newItem: Address): Boolean { 39 | return oldItem == newItem 40 | } 41 | } 42 | val differ = AsyncListDiffer(this, diffUtil) 43 | 44 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AddressViewHolder { 45 | return AddressViewHolder( 46 | AddressRvItemBinding.inflate( 47 | LayoutInflater.from(parent.context) 48 | ) 49 | ) 50 | } 51 | 52 | var selectedAddress = -1 53 | override fun onBindViewHolder(holder: AddressViewHolder, position: Int) { 54 | val address = differ.currentList[position] 55 | holder.bind(address, selectedAddress == position) 56 | 57 | holder.binding.buttonAddress.setOnClickListener { 58 | if (selectedAddress >= 0) 59 | notifyItemChanged(selectedAddress) 60 | selectedAddress = holder.adapterPosition 61 | notifyItemChanged(selectedAddress) 62 | onClick?.invoke(address) 63 | } 64 | } 65 | // 66 | init { 67 | differ.addListListener { _, _ -> 68 | notifyItemChanged(selectedAddress) 69 | } 70 | } 71 | 72 | override fun getItemCount(): Int { 73 | return differ.currentList.size 74 | } 75 | 76 | 77 | var onClick: ((Address) -> Unit)? = null 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/adapters/AllOrdersAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.adapters 2 | 3 | import android.graphics.drawable.ColorDrawable 4 | import android.view.LayoutInflater 5 | import android.view.ViewGroup 6 | import androidx.recyclerview.widget.AsyncListDiffer 7 | import androidx.recyclerview.widget.DiffUtil 8 | import androidx.recyclerview.widget.RecyclerView.Adapter 9 | import androidx.recyclerview.widget.RecyclerView.ViewHolder 10 | import com.example.kelineyt.R 11 | import com.example.kelineyt.data.order.Order 12 | import com.example.kelineyt.data.order.OrderStatus 13 | import com.example.kelineyt.data.order.getOrderStatus 14 | import com.example.kelineyt.databinding.OrderItemBinding 15 | 16 | class AllOrdersAdapter : Adapter() { 17 | 18 | inner class OrdersViewHolder(private val binding: OrderItemBinding) : ViewHolder(binding.root) { 19 | fun bind(order: Order) { 20 | binding.apply { 21 | tvOrderId.text = order.orderId.toString() 22 | tvOrderDate.text = order.date 23 | val resources = itemView.resources 24 | 25 | val colorDrawable = when (getOrderStatus(order.orderStatus)) { 26 | is OrderStatus.Ordered -> { 27 | ColorDrawable(resources.getColor(R.color.g_orange_yellow)) 28 | } 29 | is OrderStatus.Confirmed -> { 30 | ColorDrawable(resources.getColor(R.color.g_green)) 31 | } 32 | is OrderStatus.Delivered -> { 33 | ColorDrawable(resources.getColor(R.color.g_green)) 34 | } 35 | is OrderStatus.Shipped -> { 36 | ColorDrawable(resources.getColor(R.color.g_green)) 37 | } 38 | is OrderStatus.Canceled -> { 39 | ColorDrawable(resources.getColor(R.color.g_red)) 40 | } 41 | is OrderStatus.Returned -> { 42 | ColorDrawable(resources.getColor(R.color.g_red)) 43 | } 44 | } 45 | 46 | imageOrderState.setImageDrawable(colorDrawable) 47 | 48 | } 49 | } 50 | } 51 | 52 | 53 | private val diffUtil = object : DiffUtil.ItemCallback() { 54 | override fun areItemsTheSame(oldItem: Order, newItem: Order): Boolean { 55 | return oldItem.products == newItem.products 56 | } 57 | 58 | override fun areContentsTheSame(oldItem: Order, newItem: Order): Boolean { 59 | return oldItem == newItem 60 | } 61 | } 62 | 63 | val differ = AsyncListDiffer(this, diffUtil) 64 | 65 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OrdersViewHolder { 66 | return OrdersViewHolder( 67 | OrderItemBinding.inflate( 68 | LayoutInflater.from( 69 | parent.context 70 | ), 71 | parent, 72 | false 73 | ) 74 | ) 75 | } 76 | 77 | override fun onBindViewHolder(holder: OrdersViewHolder, position: Int) { 78 | val order = differ.currentList[position] 79 | holder.bind(order) 80 | 81 | holder.itemView.setOnClickListener { 82 | onClick?.invoke(order) 83 | } 84 | } 85 | 86 | override fun getItemCount(): Int { 87 | return differ.currentList.size 88 | } 89 | 90 | var onClick: ((Order) -> Unit)? = null 91 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/adapters/BestDealsAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.adapters 2 | 3 | import android.util.Log 4 | import android.view.LayoutInflater 5 | import android.view.ViewGroup 6 | import androidx.recyclerview.widget.AsyncListDiffer 7 | import androidx.recyclerview.widget.DiffUtil 8 | import androidx.recyclerview.widget.RecyclerView 9 | import com.bumptech.glide.Glide 10 | import com.example.kelineyt.data.Product 11 | import com.example.kelineyt.databinding.BestDealsRvItemBinding 12 | 13 | class BestDealsAdapter : RecyclerView.Adapter() { 14 | 15 | inner class BestDealsViewHolder(private val binding: BestDealsRvItemBinding) : 16 | RecyclerView.ViewHolder(binding.root) { 17 | fun bind(product: Product) { 18 | binding.apply { 19 | Glide.with(itemView).load(product.images[0]).into(imgBestDeal) 20 | product.offerPercentage?.let { 21 | val remainingPricePercentage = 1f - it 22 | val priceAfterOffer = remainingPricePercentage * product.price 23 | tvNewPrice.text = "$ ${String.format("%.2f",priceAfterOffer)}" 24 | } 25 | tvOldPrice.text = "$ ${product.price}" 26 | tvDealProductName.text = product.name 27 | } 28 | } 29 | } 30 | 31 | private val diffCallback = object : DiffUtil.ItemCallback() { 32 | override fun areItemsTheSame(oldItem: Product, newItem: Product): Boolean { 33 | return oldItem.id == newItem.id 34 | 35 | } 36 | 37 | override fun areContentsTheSame(oldItem: Product, newItem: Product): Boolean { 38 | return oldItem == newItem 39 | } 40 | } 41 | 42 | val differ = AsyncListDiffer(this, diffCallback) 43 | 44 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BestDealsViewHolder { 45 | return BestDealsViewHolder( 46 | BestDealsRvItemBinding.inflate( 47 | LayoutInflater.from(parent.context) 48 | ) 49 | ) 50 | } 51 | 52 | override fun onBindViewHolder(holder: BestDealsViewHolder, position: Int) { 53 | val product = differ.currentList[position] 54 | holder.bind(product) 55 | 56 | holder.itemView.setOnClickListener { 57 | onClick?.invoke(product) 58 | } 59 | 60 | } 61 | 62 | override fun getItemCount(): Int { 63 | return differ.currentList.size 64 | } 65 | 66 | var onClick: ((Product) -> Unit)? = null 67 | } 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/adapters/BestProductsAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.adapters 2 | 3 | import android.graphics.Paint 4 | import android.util.Log 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import androidx.recyclerview.widget.AsyncListDiffer 9 | import androidx.recyclerview.widget.DiffUtil 10 | import androidx.recyclerview.widget.RecyclerView 11 | import com.bumptech.glide.Glide 12 | import com.example.kelineyt.data.Product 13 | import com.example.kelineyt.databinding.ProductRvItemBinding 14 | import com.example.kelineyt.helper.getProductPrice 15 | 16 | class BestProductsAdapter : RecyclerView.Adapter() { 17 | 18 | inner class BestProductsViewHolder(private val binding: ProductRvItemBinding) : 19 | RecyclerView.ViewHolder(binding.root) { 20 | fun bind(product: Product) { 21 | binding.apply { 22 | val priceAfterOffer = product.offerPercentage.getProductPrice(product.price) 23 | tvNewPrice.text = "$ ${String.format("%.2f", priceAfterOffer)}" 24 | tvPrice.paintFlags = tvPrice.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG 25 | if (product.offerPercentage == null) 26 | tvNewPrice.visibility = View.INVISIBLE 27 | 28 | Glide.with(itemView).load(product.images[0]).into(imgProduct) 29 | tvPrice.text = "$ ${product.price}" 30 | tvName.text = product.name 31 | } 32 | 33 | } 34 | } 35 | 36 | private val diffCallback = object : DiffUtil.ItemCallback() { 37 | override fun areItemsTheSame(oldItem: Product, newItem: Product): Boolean { 38 | return oldItem.id == newItem.id 39 | 40 | } 41 | 42 | override fun areContentsTheSame(oldItem: Product, newItem: Product): Boolean { 43 | return oldItem == newItem 44 | } 45 | } 46 | 47 | val differ = AsyncListDiffer(this, diffCallback) 48 | 49 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BestProductsViewHolder { 50 | return BestProductsViewHolder( 51 | ProductRvItemBinding.inflate( 52 | LayoutInflater.from(parent.context) 53 | ) 54 | ) 55 | } 56 | 57 | override fun onBindViewHolder(holder: BestProductsViewHolder, position: Int) { 58 | val product = differ.currentList[position] 59 | holder.bind(product) 60 | 61 | holder.itemView.setOnClickListener { 62 | onClick?.invoke(product) 63 | } 64 | } 65 | 66 | override fun getItemCount(): Int { 67 | return differ.currentList.size 68 | } 69 | 70 | var onClick: ((Product) -> Unit)? = null 71 | 72 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/adapters/BillingProductsAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.adapters 2 | 3 | import android.graphics.Color 4 | import android.graphics.drawable.ColorDrawable 5 | import android.view.LayoutInflater 6 | import android.view.ViewGroup 7 | import androidx.recyclerview.widget.AsyncListDiffer 8 | import androidx.recyclerview.widget.DiffUtil 9 | import androidx.recyclerview.widget.RecyclerView.Adapter 10 | import androidx.recyclerview.widget.RecyclerView.ViewHolder 11 | import com.bumptech.glide.Glide 12 | import com.example.kelineyt.data.CartProduct 13 | import com.example.kelineyt.databinding.BillingProductsRvItemBinding 14 | import com.example.kelineyt.helper.getProductPrice 15 | 16 | class BillingProductsAdapter: Adapter() { 17 | 18 | inner class BillingProductsViewHolder(val binding: BillingProductsRvItemBinding): ViewHolder(binding.root) { 19 | 20 | fun bind(billingProduct: CartProduct) { 21 | binding.apply { 22 | Glide.with(itemView).load(billingProduct.product.images[0]).into(imageCartProduct) 23 | tvProductCartName.text = billingProduct.product.name 24 | tvBillingProductQuantity.text = billingProduct.quantity.toString() 25 | 26 | val priceAfterPercentage = billingProduct.product.offerPercentage.getProductPrice(billingProduct.product.price) 27 | tvProductCartPrice.text = "$ ${String.format("%.2f", priceAfterPercentage)}" 28 | 29 | imageCartProductColor.setImageDrawable(ColorDrawable(billingProduct.selectedColor?: Color.TRANSPARENT)) 30 | tvCartProductSize.text = billingProduct.selectedSize?:"".also { imageCartProductSize.setImageDrawable(ColorDrawable(Color.TRANSPARENT)) } 31 | } 32 | } 33 | 34 | } 35 | 36 | private val diffUtil = object : DiffUtil.ItemCallback(){ 37 | override fun areItemsTheSame(oldItem: CartProduct, newItem: CartProduct): Boolean { 38 | return oldItem.product == newItem.product 39 | } 40 | 41 | override fun areContentsTheSame(oldItem: CartProduct, newItem: CartProduct): Boolean { 42 | return oldItem == newItem 43 | } 44 | } 45 | 46 | val differ = AsyncListDiffer(this,diffUtil) 47 | 48 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BillingProductsViewHolder { 49 | return BillingProductsViewHolder( 50 | BillingProductsRvItemBinding.inflate( 51 | LayoutInflater.from(parent.context) 52 | ) 53 | ) 54 | } 55 | 56 | override fun onBindViewHolder(holder: BillingProductsViewHolder, position: Int) { 57 | val billingProduct = differ.currentList[position] 58 | 59 | holder.bind(billingProduct) 60 | } 61 | 62 | override fun getItemCount(): Int { 63 | return differ.currentList.size 64 | } 65 | 66 | 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/adapters/CartProductAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.adapters 2 | 3 | import android.graphics.Color 4 | import android.graphics.drawable.ColorDrawable 5 | import android.view.LayoutInflater 6 | import android.view.ViewGroup 7 | import androidx.recyclerview.widget.AsyncListDiffer 8 | import androidx.recyclerview.widget.DiffUtil 9 | import androidx.recyclerview.widget.RecyclerView 10 | import com.bumptech.glide.Glide 11 | import com.example.kelineyt.data.CartProduct 12 | import com.example.kelineyt.data.Product 13 | import com.example.kelineyt.databinding.CartProductItemBinding 14 | import com.example.kelineyt.helper.getProductPrice 15 | 16 | class CartProductAdapter: RecyclerView.Adapter() { 17 | 18 | inner class CartProductsViewHolder( val binding: CartProductItemBinding) : 19 | RecyclerView.ViewHolder(binding.root) { 20 | 21 | fun bind(cartProduct: CartProduct) { 22 | binding.apply { 23 | Glide.with(itemView).load(cartProduct.product.images[0]).into(imageCartProduct) 24 | tvProductCartName.text = cartProduct.product.name 25 | tvCartProductQuantity.text = cartProduct.quantity.toString() 26 | 27 | val priceAfterPercentage = cartProduct.product.offerPercentage.getProductPrice(cartProduct.product.price) 28 | tvProductCartPrice.text = "$ ${String.format("%.2f", priceAfterPercentage)}" 29 | 30 | imageCartProductColor.setImageDrawable(ColorDrawable(cartProduct.selectedColor?: Color.TRANSPARENT)) 31 | tvCartProductSize.text = cartProduct.selectedSize?:"".also { imageCartProductSize.setImageDrawable(ColorDrawable(Color.TRANSPARENT)) } 32 | } 33 | } 34 | } 35 | 36 | private val diffCallback = object : DiffUtil.ItemCallback() { 37 | override fun areItemsTheSame(oldItem: CartProduct, newItem: CartProduct): Boolean { 38 | return oldItem.product.id == newItem.product.id 39 | } 40 | 41 | override fun areContentsTheSame(oldItem: CartProduct, newItem: CartProduct): Boolean { 42 | return oldItem == newItem 43 | } 44 | } 45 | 46 | val differ = AsyncListDiffer(this, diffCallback) 47 | 48 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CartProductsViewHolder { 49 | return CartProductsViewHolder( 50 | CartProductItemBinding.inflate( 51 | LayoutInflater.from(parent.context), parent, false 52 | ) 53 | ) 54 | } 55 | 56 | override fun onBindViewHolder(holder: CartProductsViewHolder, position: Int) { 57 | val cartProduct = differ.currentList[position] 58 | holder.bind(cartProduct) 59 | 60 | holder.itemView.setOnClickListener { 61 | onProductClick?.invoke(cartProduct) 62 | } 63 | 64 | holder.binding.imagePlus.setOnClickListener { 65 | onPlusClick?.invoke(cartProduct) 66 | } 67 | 68 | holder.binding.imageMinus.setOnClickListener { 69 | onMinusClick?.invoke(cartProduct) 70 | } 71 | } 72 | 73 | override fun getItemCount(): Int { 74 | return differ.currentList.size 75 | } 76 | 77 | var onProductClick: ((CartProduct) -> Unit)? = null 78 | var onPlusClick: ((CartProduct) -> Unit)? = null 79 | var onMinusClick: ((CartProduct) -> Unit)? = null 80 | 81 | 82 | 83 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/adapters/ColorsAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.adapters 2 | 3 | import android.graphics.drawable.ColorDrawable 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.recyclerview.widget.AsyncListDiffer 8 | import androidx.recyclerview.widget.DiffUtil 9 | import androidx.recyclerview.widget.RecyclerView 10 | import androidx.recyclerview.widget.RecyclerView.ViewHolder 11 | import com.example.kelineyt.databinding.ColorRvItemBinding 12 | 13 | class ColorsAdapter : RecyclerView.Adapter() { 14 | 15 | private var selectedPosition = -1 16 | 17 | inner class ColorsViewHolder(private val binding: ColorRvItemBinding) : 18 | ViewHolder(binding.root) { 19 | fun bind(color: Int, position: Int) { 20 | val imageDrawable = ColorDrawable(color) 21 | binding.imageColor.setImageDrawable(imageDrawable) 22 | if (position == selectedPosition) { //Color is selected 23 | binding.apply { 24 | imageShadow.visibility = View.VISIBLE 25 | imagePicked.visibility = View.VISIBLE 26 | } 27 | } else { //Color is not selected 28 | binding.apply { 29 | imageShadow.visibility = View.INVISIBLE 30 | imagePicked.visibility = View.INVISIBLE 31 | } 32 | } 33 | } 34 | } 35 | 36 | private val diffCallback = object : DiffUtil.ItemCallback() { 37 | override fun areItemsTheSame(oldItem: Int, newItem: Int): Boolean { 38 | return oldItem == newItem 39 | } 40 | 41 | override fun areContentsTheSame(oldItem: Int, newItem: Int): Boolean { 42 | return oldItem == newItem 43 | } 44 | } 45 | 46 | val differ = AsyncListDiffer(this, diffCallback) 47 | 48 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColorsViewHolder { 49 | return ColorsViewHolder( 50 | ColorRvItemBinding.inflate( 51 | LayoutInflater.from(parent.context) 52 | ) 53 | ) 54 | } 55 | 56 | override fun onBindViewHolder(holder: ColorsViewHolder, position: Int) { 57 | val color = differ.currentList[position] 58 | holder.bind(color, position) 59 | 60 | holder.itemView.setOnClickListener { 61 | if (selectedPosition >= 0) 62 | notifyItemChanged(selectedPosition) 63 | selectedPosition = holder.adapterPosition 64 | notifyItemChanged(selectedPosition) 65 | onItemClick?.invoke(color) 66 | } 67 | } 68 | 69 | override fun getItemCount(): Int { 70 | return differ.currentList.size 71 | } 72 | 73 | var onItemClick: ((Int) -> Unit)? = null 74 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/adapters/HomeViewpagerAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.adapters 2 | 3 | import android.util.Log 4 | import androidx.fragment.app.Fragment 5 | import androidx.fragment.app.FragmentManager 6 | import androidx.lifecycle.Lifecycle 7 | import androidx.viewpager2.adapter.FragmentStateAdapter 8 | 9 | class HomeViewpagerAdapter( 10 | private val fragments: List, 11 | fm: FragmentManager, 12 | lifecycle: Lifecycle 13 | ):FragmentStateAdapter(fm,lifecycle) { 14 | 15 | override fun getItemCount(): Int { 16 | return fragments.size 17 | } 18 | 19 | override fun createFragment(position: Int): Fragment { 20 | return fragments[position] 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/adapters/SizesAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.adapters 2 | 3 | import android.graphics.drawable.ColorDrawable 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.recyclerview.widget.AsyncListDiffer 8 | import androidx.recyclerview.widget.DiffUtil 9 | import androidx.recyclerview.widget.RecyclerView 10 | import com.example.kelineyt.databinding.SizeRvItemBinding 11 | 12 | class SizesAdapter: RecyclerView.Adapter() { 13 | 14 | private var selectedPosition = -1 15 | 16 | inner class SizesViewHolder(private val binding: SizeRvItemBinding) : 17 | RecyclerView.ViewHolder(binding.root) { 18 | fun bind(size: String, position: Int) { 19 | binding.tvSize.text = size 20 | if (position == selectedPosition) { //Size is selected 21 | binding.apply { 22 | imageShadow.visibility = View.VISIBLE 23 | } 24 | } else { //Size is not selected 25 | binding.apply { 26 | imageShadow.visibility = View.INVISIBLE 27 | } 28 | } 29 | } 30 | } 31 | 32 | private val diffCallback = object : DiffUtil.ItemCallback() { 33 | override fun areItemsTheSame(oldItem: String, newItem: String): Boolean { 34 | return oldItem == newItem 35 | } 36 | 37 | override fun areContentsTheSame(oldItem: String, newItem: String): Boolean { 38 | return oldItem == newItem 39 | } 40 | } 41 | 42 | val differ = AsyncListDiffer(this, diffCallback) 43 | 44 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SizesViewHolder { 45 | return SizesViewHolder( 46 | SizeRvItemBinding.inflate( 47 | LayoutInflater.from(parent.context) 48 | ) 49 | ) 50 | } 51 | 52 | override fun onBindViewHolder(holder: SizesViewHolder, position: Int) { 53 | val size = differ.currentList[position] 54 | holder.bind(size, position) 55 | 56 | holder.itemView.setOnClickListener { 57 | if (selectedPosition >= 0) 58 | notifyItemChanged(selectedPosition) 59 | selectedPosition = holder.adapterPosition 60 | notifyItemChanged(selectedPosition) 61 | onItemClick?.invoke(size) 62 | } 63 | } 64 | 65 | override fun getItemCount(): Int { 66 | return differ.currentList.size 67 | } 68 | 69 | var onItemClick: ((String) -> Unit)? = null 70 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/adapters/SpecialProductsAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.adapters 2 | 3 | import android.view.LayoutInflater 4 | import android.view.ViewGroup 5 | import androidx.recyclerview.widget.AsyncListDiffer 6 | import androidx.recyclerview.widget.DiffUtil 7 | import androidx.recyclerview.widget.RecyclerView 8 | import com.bumptech.glide.Glide 9 | import com.example.kelineyt.data.Product 10 | import com.example.kelineyt.databinding.SpecialRvItemBinding 11 | 12 | class SpecialProductsAdapter : 13 | RecyclerView.Adapter() { 14 | 15 | inner class SpecialProductsViewHolder(private val binding: SpecialRvItemBinding) : 16 | RecyclerView.ViewHolder(binding.root) { 17 | 18 | fun bind(product: Product) { 19 | binding.apply { 20 | Glide.with(itemView).load(product.images[0]).into(imageSpecialRvItem) 21 | tvSpecialProductName.text = product.name 22 | tvSpecialPrdouctPrice.text = product.price.toString() 23 | } 24 | } 25 | } 26 | 27 | private val diffCallback = object : DiffUtil.ItemCallback() { 28 | override fun areItemsTheSame(oldItem: Product, newItem: Product): Boolean { 29 | return oldItem.id == newItem.id 30 | } 31 | 32 | override fun areContentsTheSame(oldItem: Product, newItem: Product): Boolean { 33 | return oldItem == newItem 34 | } 35 | } 36 | 37 | val differ = AsyncListDiffer(this, diffCallback) 38 | 39 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SpecialProductsViewHolder { 40 | return SpecialProductsViewHolder( 41 | SpecialRvItemBinding.inflate( 42 | LayoutInflater.from(parent.context), parent, false 43 | ) 44 | ) 45 | } 46 | 47 | override fun onBindViewHolder(holder: SpecialProductsViewHolder, position: Int) { 48 | val product = differ.currentList[position] 49 | holder.bind(product) 50 | 51 | holder.itemView.setOnClickListener { 52 | onClick?.invoke(product) 53 | } 54 | } 55 | 56 | override fun getItemCount(): Int { 57 | return differ.currentList.size 58 | } 59 | 60 | var onClick: ((Product) -> Unit)? = null 61 | 62 | } 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/adapters/ViewPager2Images.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.adapters 2 | 3 | import android.view.LayoutInflater 4 | import android.view.ViewGroup 5 | import androidx.recyclerview.widget.AsyncListDiffer 6 | import androidx.recyclerview.widget.DiffUtil 7 | import androidx.recyclerview.widget.RecyclerView 8 | import androidx.recyclerview.widget.RecyclerView.ViewHolder 9 | import com.bumptech.glide.Glide 10 | import com.example.kelineyt.databinding.ViewpagerImageItemBinding 11 | 12 | class ViewPager2Images : RecyclerView.Adapter() { 13 | 14 | inner class ViewPager2ImagesViewHolder(val binding: ViewpagerImageItemBinding) : 15 | ViewHolder(binding.root) { 16 | 17 | fun bind(imagePath: String){ 18 | Glide.with(itemView).load(imagePath).into(binding.imageProductDetails) 19 | } 20 | } 21 | 22 | private val diffCallback = object : DiffUtil.ItemCallback() { 23 | override fun areItemsTheSame(oldItem: String, newItem: String): Boolean { 24 | return oldItem == newItem 25 | } 26 | 27 | override fun areContentsTheSame(oldItem: String, newItem: String): Boolean { 28 | return oldItem == newItem 29 | } 30 | } 31 | 32 | val differ = AsyncListDiffer(this, diffCallback) 33 | 34 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewPager2ImagesViewHolder { 35 | return ViewPager2ImagesViewHolder( 36 | ViewpagerImageItemBinding.inflate( 37 | LayoutInflater.from(parent.context), parent, false 38 | ) 39 | ) 40 | } 41 | 42 | override fun onBindViewHolder(holder: ViewPager2ImagesViewHolder, position: Int) { 43 | val image = differ.currentList[position] 44 | holder.bind(image) 45 | } 46 | 47 | override fun getItemCount(): Int { 48 | return differ.currentList.size 49 | } 50 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/data/Address.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.data 2 | 3 | import android.os.Parcelable 4 | import kotlinx.parcelize.Parcelize 5 | 6 | @Parcelize 7 | data class Address( 8 | val addressTitle: String, 9 | val fullName: String, 10 | val street: String, 11 | val phone: String, 12 | val city: String, 13 | val state: String 14 | ): Parcelable { 15 | 16 | constructor(): this("","","","","","") 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/data/CartProduct.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.data 2 | 3 | import android.os.Parcelable 4 | import kotlinx.parcelize.Parcelize 5 | 6 | @Parcelize 7 | data class CartProduct( 8 | val product: Product, 9 | val quantity: Int, 10 | val selectedColor: Int? = null, 11 | val selectedSize: String? = null 12 | ): Parcelable { 13 | constructor() : this(Product(), 1, null, null) 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/data/Category.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.data 2 | 3 | sealed class Category(val category: String) { 4 | 5 | object Chair: Category("Chair") 6 | object Cupboard: Category("Cupboard") 7 | object Table: Category("Table") 8 | object Accessory: Category("Accessory") 9 | object Furniture: Category("Furniture") 10 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/data/Product.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.data 2 | 3 | import android.os.Parcelable 4 | import kotlinx.parcelize.Parcelize 5 | 6 | @Parcelize 7 | data class Product( 8 | val id: String, 9 | val name: String, 10 | val category: String, 11 | val price: Float, 12 | val offerPercentage: Float? = null, 13 | val description: String? = null, 14 | val colors: List? = null, 15 | val sizes: List? = null, 16 | val images: List 17 | ): Parcelable { 18 | constructor():this("0","","",0f,images = emptyList()) 19 | 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/data/User.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.data 2 | 3 | data class User( 4 | val firstName: String, 5 | val lastName: String, 6 | val email: String, 7 | var imagePath: String = "" 8 | ){ 9 | constructor(): this("","","","") 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/data/order/Order.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.data.order 2 | 3 | import android.os.Parcelable 4 | import com.example.kelineyt.data.Address 5 | import com.example.kelineyt.data.CartProduct 6 | import kotlinx.parcelize.Parcelize 7 | import java.text.SimpleDateFormat 8 | import java.util.* 9 | import kotlin.random.Random.Default.nextLong 10 | 11 | @Parcelize 12 | data class Order( 13 | val orderStatus: String = "", 14 | val totalPrice: Float = 0f, 15 | val products: List = emptyList(), 16 | val address: Address = Address(), 17 | val date: String = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).format(Date()), 18 | val orderId: Long = nextLong(0,100_000_000_000) + totalPrice.toLong() 19 | ): Parcelable -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/data/order/OrderStatus.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.data.order 2 | 3 | sealed class OrderStatus(val status: String) { 4 | 5 | object Ordered: OrderStatus("Ordered") 6 | object Canceled: OrderStatus("Canceled") 7 | object Confirmed: OrderStatus("Confirmed") 8 | object Shipped: OrderStatus("Shipped") 9 | object Delivered: OrderStatus("Delivered") 10 | object Returned: OrderStatus("Returned") 11 | } 12 | 13 | fun getOrderStatus(status: String): OrderStatus { 14 | return when (status) { 15 | "Ordered" -> { 16 | OrderStatus.Ordered 17 | } 18 | "Canceled" -> { 19 | OrderStatus.Canceled 20 | } 21 | "Confirmed" -> { 22 | OrderStatus.Confirmed 23 | } 24 | "Shipped" -> { 25 | OrderStatus.Shipped 26 | } 27 | "Delivered" -> { 28 | OrderStatus.Delivered 29 | } 30 | else -> OrderStatus.Returned 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/di/AppModule.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.di 2 | 3 | import android.app.Application 4 | import android.content.Context.MODE_PRIVATE 5 | import com.example.kelineyt.firebase.FirebaseCommon 6 | import com.example.kelineyt.util.Constants.INTRODUCTION_SP 7 | import com.google.firebase.auth.FirebaseAuth 8 | import com.google.firebase.firestore.FirebaseFirestore 9 | import com.google.firebase.firestore.ktx.firestore 10 | import com.google.firebase.ktx.Firebase 11 | import com.google.firebase.storage.FirebaseStorage 12 | import dagger.Module 13 | import dagger.Provides 14 | import dagger.hilt.InstallIn 15 | import dagger.hilt.components.SingletonComponent 16 | import javax.inject.Singleton 17 | 18 | @Module 19 | @InstallIn(SingletonComponent::class) 20 | object AppModule { 21 | 22 | @Provides 23 | @Singleton 24 | fun provideFirebaseAuth() = FirebaseAuth.getInstance() 25 | 26 | @Provides 27 | @Singleton 28 | fun provideFirebaseFirestoreDatabase() = Firebase.firestore 29 | 30 | @Provides 31 | fun provideIntroductionSP( 32 | application: Application 33 | ) = application.getSharedPreferences(INTRODUCTION_SP, MODE_PRIVATE) 34 | 35 | @Provides 36 | @Singleton 37 | fun provideFirebaseCommon( 38 | firebaseAuth: FirebaseAuth, 39 | firestore: FirebaseFirestore 40 | ) = FirebaseCommon(firestore,firebaseAuth) 41 | 42 | @Provides 43 | @Singleton 44 | fun provideStorage() = FirebaseStorage.getInstance().reference 45 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/kelineyt/dialog/ResetPasswordDialog.kt: -------------------------------------------------------------------------------- 1 | package com.example.kelineyt.dialog 2 | 3 | import android.widget.Button 4 | import android.widget.EditText 5 | import androidx.fragment.app.Fragment 6 | import com.example.kelineyt.R 7 | import com.google.android.material.bottomsheet.BottomSheetBehavior 8 | import com.google.android.material.bottomsheet.BottomSheetDialog 9 | 10 | fun Fragment.setupBottomSheetDialog( 11 | onSendClick: (String) -> Unit 12 | ){ 13 | val dialog = BottomSheetDialog(requireContext(),R.style.DialogStyle) 14 | val view = layoutInflater.inflate(R.layout.reset_passowrd_dialog,null) 15 | dialog.setContentView(view) 16 | dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED 17 | dialog.show() 18 | 19 | val edEmail = view.findViewById(R.id.edResetPassword) 20 | val buttonSend = view.findViewById