diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 91853b6..b3e2bea 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.application") id("org.jetbrains.kotlin.android") id("kotlin-kapt") + id("kotlin-parcelize") } android { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1aadf3d..c02f5cb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,7 +14,7 @@ android:theme="@style/Theme.Project" tools:targetApi="31"> + + + dataBase.getUserDao().getUserByEmail(it1) } } + + val favoriteDishes:List = user?.favoriteDishesId ?: emptyList() + if (favoriteDishes.contains(dish.id)) { + val updatedDishes: List = favoriteDishes.filter { it != dish.id } + dataBase.getUserDao().updateFavoriteDishes(user?.id!!, updatedDishes) + } else { + val updatedDishes = favoriteDishes + dish.id + dataBase.getUserDao().updateFavoriteDishes(user?.id!!, updatedDishes) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/Activity/HomeActivity.kt b/app/src/main/java/com/example/projectfigma/Activity/HomeActivity.kt index 60a87ba..cb93b7f 100644 --- a/app/src/main/java/com/example/projectfigma/Activity/HomeActivity.kt +++ b/app/src/main/java/com/example/projectfigma/Activity/HomeActivity.kt @@ -1,6 +1,8 @@ package com.example.projectfigma.Activity +import android.content.Intent import android.os.Bundle +import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.view.GravityCompat @@ -16,6 +18,7 @@ import com.example.projectfigma.Entites.User import com.example.projectfigma.Fragments.* import com.example.projectfigma.R import com.example.projectfigma.Util.StatusBar +import com.example.projectfigma.Util.SwitchCard class HomeActivity : AppCompatActivity(), HeaderButtonsFragment.Listener { @@ -32,8 +35,6 @@ class HomeActivity : AppCompatActivity(), setContentView(R.layout.activity_home) StatusBar.hideStatusBar(window) - drawer = findViewById(R.id.drawer_layout) - val db = DataBase.getDb(this) dao = db.getDishesDao() userDao = db.getUserDao() @@ -43,19 +44,22 @@ class HomeActivity : AppCompatActivity(), user = userDao.getUserByEmail(email) } + drawer = findViewById(R.id.drawer_layout) + + adapter = BestSellerAdapter(emptyList()) { item -> + SwitchCard.switchDish( + item, + this, + FoodDetailActivity::class.java + ) + } val rv = findViewById(R.id.rvBestSellers).apply { layoutManager = LinearLayoutManager( this@HomeActivity, LinearLayoutManager.HORIZONTAL, false ) - adapter = BestSellerAdapter(emptyList()) { item: Dishes -> - Toast.makeText( - this@HomeActivity, - "Clicked: ${item.price}", - Toast.LENGTH_SHORT - ).show() - }.also { this@HomeActivity.adapter = it } + adapter = this@HomeActivity.adapter } dao.getBestSellersWithLimit(4).observe(this) { list -> diff --git a/app/src/main/java/com/example/projectfigma/Activity/RecomendationActivity.kt b/app/src/main/java/com/example/projectfigma/Activity/RecomendationActivity.kt new file mode 100644 index 0000000..4bc6000 --- /dev/null +++ b/app/src/main/java/com/example/projectfigma/Activity/RecomendationActivity.kt @@ -0,0 +1,28 @@ +package com.example.projectfigma.Activity + +import android.os.Bundle +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import com.example.projectfigma.Fragments.BottomPanelFragment +import com.example.projectfigma.R +import com.example.projectfigma.Util.StatusBar +import com.example.projectfigma.databinding.ActivityAdvertisingPageBinding +import com.example.projectfigma.databinding.ActivityRecomendationBinding + +class RecomendationActivity : AppCompatActivity() { + private lateinit var binding: ActivityRecomendationBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + binding = ActivityRecomendationBinding.inflate(layoutInflater) + setContentView(binding.root) + StatusBar.hideStatusBar(window) + + supportFragmentManager.beginTransaction() + .replace(R.id.buttonPanel, BottomPanelFragment()) + .commit() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/Adapters/BestSellerAdapter.kt b/app/src/main/java/com/example/projectfigma/Adapters/BestSellerAdapter.kt index 0a02bb3..87a33be 100644 --- a/app/src/main/java/com/example/projectfigma/Adapters/BestSellerAdapter.kt +++ b/app/src/main/java/com/example/projectfigma/Adapters/BestSellerAdapter.kt @@ -12,7 +12,7 @@ import com.example.projectfigma.R class BestSellerAdapter( private var items: List, - private val onClick: (Dishes) -> Unit + private val switchToSelfPage: (Dishes) -> Unit ) : RecyclerView.Adapter() { inner class VH(view: View) : RecyclerView.ViewHolder(view) { @@ -26,7 +26,7 @@ class BestSellerAdapter( .centerCrop() .into(ivFood) - itemView.setOnClickListener { onClick(item) } + itemView.setOnClickListener { switchToSelfPage(item) } } } diff --git a/app/src/main/java/com/example/projectfigma/Adapters/FavoriteDishesAdapter.kt b/app/src/main/java/com/example/projectfigma/Adapters/FavoriteDishesAdapter.kt index e06498b..4d8a8ba 100644 --- a/app/src/main/java/com/example/projectfigma/Adapters/FavoriteDishesAdapter.kt +++ b/app/src/main/java/com/example/projectfigma/Adapters/FavoriteDishesAdapter.kt @@ -15,7 +15,8 @@ import kotlin.coroutines.coroutineContext class FavoriteFoodAdapter( private val items: MutableList, - private val onFavoriteClick: (dish: Dishes) -> Unit + private val onFavoriteClick: (dish: Dishes) -> Unit, + private val switchToSelfPage: (Dishes) -> Unit ) : RecyclerView.Adapter() { inner class VH(view: View) : RecyclerView.ViewHolder(view) { @@ -46,6 +47,8 @@ class FavoriteFoodAdapter( holder.imgFavorite.setImageResource(R.drawable.ic_heart_border) holder.imgFavorite.setOnClickListener { onFavoriteClick(dish) } + + holder.itemView.setOnClickListener { switchToSelfPage(dish) } } override fun getItemCount(): Int = items.size diff --git a/app/src/main/java/com/example/projectfigma/Adapters/MainBestSellerAdapter.kt b/app/src/main/java/com/example/projectfigma/Adapters/MainBestSellerAdapter.kt new file mode 100644 index 0000000..855b4a0 --- /dev/null +++ b/app/src/main/java/com/example/projectfigma/Adapters/MainBestSellerAdapter.kt @@ -0,0 +1,56 @@ +package com.example.projectfigma.Adapters + +import android.net.Uri +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.example.projectfigma.Entites.Dishes +import com.example.projectfigma.R + +class MainBestSellerAdapter ( + private var dishes: List, + private val switchToSelfPage: (Dishes) -> Unit +) : + RecyclerView.Adapter() { + + inner class DishViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val image: ImageView = itemView.findViewById(R.id.dishImage) + val title: TextView = itemView.findViewById(R.id.dishTitle) + val description: TextView = itemView.findViewById(R.id.dishDescription) + val price: TextView = itemView.findViewById(R.id.dishPrice) + val rating: TextView = itemView.findViewById(R.id.tvRating) + val category: ImageView = itemView.findViewById(R.id.iconCategory) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DishViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.item_dish_best_seller, parent, false) + return DishViewHolder(view) + } + + override fun onBindViewHolder(holder: DishViewHolder, position: Int) { + val dish = dishes[position] + + Glide.with(holder.itemView.context) + .load(Uri.parse(dish.imageUri)) + .into(holder.image) + + holder.category.setImageResource(dish.category.iconRes) + holder.title.text = dish.name + holder.description.text = dish.description + holder.price.text = "$${dish.price}" + holder.rating.text = "${dish.rating}" + + holder.itemView.setOnClickListener { switchToSelfPage(dish) } + } + + override fun getItemCount(): Int = dishes.size + + fun updateData(newList: List) { + dishes = newList + notifyDataSetChanged() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/Adapters/MainRecommendAdapter.kt b/app/src/main/java/com/example/projectfigma/Adapters/MainRecommendAdapter.kt new file mode 100644 index 0000000..b0584b5 --- /dev/null +++ b/app/src/main/java/com/example/projectfigma/Adapters/MainRecommendAdapter.kt @@ -0,0 +1,53 @@ +package com.example.projectfigma.Adapters + +import android.net.Uri +import android.view.View +import android.view.ViewGroup +import android.view.LayoutInflater +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.example.projectfigma.Entites.Dishes +import com.example.projectfigma.R + +class MainRecommendAdapter( + private var dishes: List, + private val switchToSelfPage: (Dishes) -> Unit +) : RecyclerView.Adapter() { + + inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { + val imgFood: ImageView = view.findViewById(R.id.imgFood) + val imgCategory: ImageView = view.findViewById(R.id.imgCategory) + val tvTitle: TextView = view.findViewById(R.id.tvTitle) + val tvDesc: TextView = view.findViewById(R.id.tvDesc) + val tvPrice: TextView = view.findViewById(R.id.tvPrice) + val tvRating: TextView = view.findViewById(R.id.tvRating) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val v = LayoutInflater.from(parent.context) + .inflate(R.layout.item_main_recomend, parent, false) + return ViewHolder(v) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val dish = dishes[position] + + Glide.with(holder.itemView.context) + .load(Uri.parse(dish.imageUri)) + .into(holder.imgFood) + holder.imgCategory.setImageResource(dish.category.iconRes) + holder.tvTitle.text = dish.name + holder.tvDesc.text = dish.description + holder.tvPrice.text = "$" + dish.price.toString() + holder.tvRating.text = dish.rating.toString() + + holder.itemView.setOnClickListener { switchToSelfPage(dish) } + } + + override fun getItemCount(): Int = dishes.size + fun updateData(newItems: List) { + dishes = newItems + } +} diff --git a/app/src/main/java/com/example/projectfigma/Adapters/PromoAdapter.kt b/app/src/main/java/com/example/projectfigma/Adapters/PromoAdapter.kt index 6ea3eb8..ecd3dbc 100644 --- a/app/src/main/java/com/example/projectfigma/Adapters/PromoAdapter.kt +++ b/app/src/main/java/com/example/projectfigma/Adapters/PromoAdapter.kt @@ -5,21 +5,27 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import androidx.cardview.widget.CardView import androidx.recyclerview.widget.RecyclerView import com.example.projectfigma.Entites.Dishes import com.example.projectfigma.R -class PromoAdapter(private var items: List) : +class PromoAdapter( + private var items: List, + private val onBannerClick: () -> Unit +) : RecyclerView.Adapter() { inner class VH(view: View) : RecyclerView.ViewHolder(view) { private val image: ImageView = view.findViewById(R.id.promo_image) private val title: TextView = view.findViewById(R.id.title) private val discount: TextView = view.findViewById(R.id.discount) + private val fullCard: CardView = view.findViewById(R.id.fullCard) fun bind(item: Dishes) { title.text = "Experience our delicious new dish" discount.text = "${30}% OFF" + fullCard.setOnClickListener { onBannerClick() } } } diff --git a/app/src/main/java/com/example/projectfigma/Adapters/RecommendAdapter.kt b/app/src/main/java/com/example/projectfigma/Adapters/RecommendAdapter.kt index 85f6cb6..ab4235c 100644 --- a/app/src/main/java/com/example/projectfigma/Adapters/RecommendAdapter.kt +++ b/app/src/main/java/com/example/projectfigma/Adapters/RecommendAdapter.kt @@ -11,7 +11,8 @@ import com.example.projectfigma.Entites.Dishes import com.example.projectfigma.R class RecommendAdapter ( - private val items: List + private val items: List, + private val switchToSelfPage: (Dishes) -> Unit ) : RecyclerView.Adapter() { inner class VH(itemView: View) : RecyclerView.ViewHolder(itemView) { @@ -23,6 +24,7 @@ class RecommendAdapter ( Glide.with(itemView).load(food.imageUri).into(ivFood) tvRating.text = String.format("%.1f", food.rating) tvPrice.text = "$${String.format("%.2f", food.price)}" + itemView.setOnClickListener { switchToSelfPage(food) } } } diff --git a/app/src/main/java/com/example/projectfigma/DAO/DishesDao.kt b/app/src/main/java/com/example/projectfigma/DAO/DishesDao.kt index ee99af3..1c761df 100644 --- a/app/src/main/java/com/example/projectfigma/DAO/DishesDao.kt +++ b/app/src/main/java/com/example/projectfigma/DAO/DishesDao.kt @@ -40,4 +40,25 @@ interface DishesDao { @Update suspend fun update(item: Dishes) + + //Сортировка по популярности (например, по рейтингу) + @Query("SELECT * FROM dishes ORDER BY rating DESC") + fun getSortedByRating(): LiveData> + + //Сортировка по цене (возрастание) + @Query("SELECT * FROM dishes ORDER BY price ASC") + fun getSortedByPriceAsc(): LiveData> + + //Сортировка по цене (убывание) + @Query("SELECT * FROM dishes ORDER BY price DESC") + fun getSortedByPriceDesc(): LiveData> + + @Query("SELECT * FROM Dishes ORDER BY rating DESC") + suspend fun getAllSortedByRating(): List + + @Query("SELECT * FROM Dishes ORDER BY price ASC") + suspend fun getAllSortedByPrice(): List + + @Query("SELECT * FROM Dishes ORDER BY ordersCount DESC") + suspend fun getAllSortedByPopularity(): List } \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/DAO/UserDao.kt b/app/src/main/java/com/example/projectfigma/DAO/UserDao.kt index 0badd54..e973560 100644 --- a/app/src/main/java/com/example/projectfigma/DAO/UserDao.kt +++ b/app/src/main/java/com/example/projectfigma/DAO/UserDao.kt @@ -28,4 +28,14 @@ interface UserDao { @Query("SELECT * FROM USERS u WHERE u.gmail LIKE :email") fun getUserByEmail(email : String) : User + + @Query(""" + UPDATE users + SET favoriteDishesId = :favoriteDishes + WHERE id = :userId + """) + suspend fun updateFavoriteDishes( + userId: Int, + favoriteDishes: List + ) } \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/DataBase/DataBase.kt b/app/src/main/java/com/example/projectfigma/DataBase/DataBase.kt index cf15fbd..92d1cf1 100644 --- a/app/src/main/java/com/example/projectfigma/DataBase/DataBase.kt +++ b/app/src/main/java/com/example/projectfigma/DataBase/DataBase.kt @@ -28,7 +28,7 @@ import java.util.Date @Database( entities = [User::class, Dishes::class, Session::class, AppSettings::class], - version = 6 + version = 9 ) @TypeConverters( ConvertersToDateTime::class, @@ -129,7 +129,67 @@ abstract class DataBase : RoomDatabase() { name = "Роллы", description = "Роллы", category = DishCategory.VEGAN - ) + ), + Dishes( + imageUri = "android.resource://$packageName/${R.drawable.into_best_seller1}", + price = 15.0, + isBestSeller = true, + isRecommend = false, + rating = 5.0, + name = "Солнечная брускетта", + description = "Солнечная брускетта", + category = DishCategory.SNACKS + ), + Dishes( + imageUri = "android.resource://$packageName/${R.drawable.into_best_seller2}", + price = 12.0, + isBestSeller = true, + isRecommend = false, + rating = 4.5, + name = "Изысканные шашлыки на гриле", + description = "Изысканные шашлыки на гриле", + category = DishCategory.SNACKS + ), + Dishes( + imageUri = "android.resource://$packageName/${R.drawable.into_best_seller3}", + price = 15.0, + isBestSeller = true, + isRecommend = false, + rating = 4.0, + name = "Тако с барбекю", + description = "Тако с барбекю", + category = DishCategory.MEAL + ), + Dishes( + imageUri = "android.resource://$packageName/${R.drawable.into_best_seller4}", + price = 12.0, + isBestSeller = true, + isRecommend = false, + rating = 3.5, + name = "Лазанья из брокколи", + description = "Лазанья из брокколи", + category = DishCategory.VEGAN + ), + Dishes( + imageUri = "android.resource://$packageName/${R.drawable.into_best_seller5}", + price = 15.0, + isBestSeller = true, + isRecommend = false, + rating = 3.0, + name = "Снежный кофе", + description = "Снежный кофе", + category = DishCategory.DRINKS + ), + Dishes( + imageUri = "android.resource://$packageName/${R.drawable.into_best_seller6}", + price = 12.0, + isBestSeller = true, + isRecommend = false, + rating = 4.0, + name = "Клубничный чизкейк", + description = "Клубничный чизкейк", + category = DishCategory.DESERT + ), ) fun getDb(context: Context): DataBase { diff --git a/app/src/main/java/com/example/projectfigma/Entites/Basket.kt b/app/src/main/java/com/example/projectfigma/Entites/Basket.kt new file mode 100644 index 0000000..495a713 --- /dev/null +++ b/app/src/main/java/com/example/projectfigma/Entites/Basket.kt @@ -0,0 +1,10 @@ +package com.example.projectfigma.Entites + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "baskets") +data class Basket ( + @PrimaryKey(autoGenerate = true) val id: Long = 0, + val dishesIds: List +) \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/Entites/Dishes.kt b/app/src/main/java/com/example/projectfigma/Entites/Dishes.kt index cee6616..986fdda 100644 --- a/app/src/main/java/com/example/projectfigma/Entites/Dishes.kt +++ b/app/src/main/java/com/example/projectfigma/Entites/Dishes.kt @@ -1,18 +1,22 @@ package com.example.projectfigma.Entites +import android.os.Parcelable import androidx.room.Entity import androidx.room.PrimaryKey import com.example.projectfigma.Enums.DishCategory +import kotlinx.android.parcel.Parcelize +@Parcelize @Entity(tableName = "dishes") data class Dishes( - @PrimaryKey(autoGenerate = true) val id: Long = 0, + @PrimaryKey(autoGenerate = true) val id: Int = 0, val imageUri: String, val price: Double, val rating: Double, val isRecommend: Boolean, val isBestSeller: Boolean, - val name: String, - val description: String, - val category: DishCategory -) \ No newline at end of file + val name : String, + val description : String, + val category: DishCategory, + val ordersCount: Int = 0 +) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/Entites/Session.kt b/app/src/main/java/com/example/projectfigma/Entites/Session.kt index 5c6b57e..450e7f3 100644 --- a/app/src/main/java/com/example/projectfigma/Entites/Session.kt +++ b/app/src/main/java/com/example/projectfigma/Entites/Session.kt @@ -7,5 +7,5 @@ import androidx.room.PrimaryKey data class Session( @PrimaryKey val id: Int = 0, // единственная запись val isLoggedIn: Boolean, - val userEmail: String? // email или null + val userEmail: String? // email или null ) diff --git a/app/src/main/java/com/example/projectfigma/Fragments/BannerFood.kt b/app/src/main/java/com/example/projectfigma/Fragments/BannerFood.kt index 56d489c..5a79906 100644 --- a/app/src/main/java/com/example/projectfigma/Fragments/BannerFood.kt +++ b/app/src/main/java/com/example/projectfigma/Fragments/BannerFood.kt @@ -1,5 +1,6 @@ package com.example.projectfigma.Fragments +import android.content.Intent import android.os.Bundle import android.os.Handler import android.os.Looper @@ -7,79 +8,83 @@ import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.lifecycle.lifecycleScope import androidx.viewpager2.widget.ViewPager2 +import com.example.projectfigma.Activity.AdverstsingPageActivity +import com.example.projectfigma.Activity.FoodDetailActivity +import com.example.projectfigma.Activity.LogActivity import com.example.projectfigma.Adapters.PromoAdapter import com.example.projectfigma.DataBase.DataBase import com.example.projectfigma.R +import com.example.projectfigma.Util.SwitchCard import com.example.projectfigma.databinding.FragmentBannerFoodBinding import com.example.projectfigma.databinding.FragmentBestSellerBinding import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class BannerFood : Fragment() { private var _binding: FragmentBannerFoodBinding? = null private val binding get() = _binding!! private lateinit var promoAdapter: PromoAdapter - - override fun onCreate(savedInstanceState: Bundle?) { - - super.onCreate(savedInstanceState) + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentBannerFoodBinding.inflate(inflater, container, false) + return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - // 1) Инициализируем адаптер - promoAdapter = PromoAdapter(emptyList()) + promoAdapter = PromoAdapter(emptyList(), + onBannerClick = { + val intent = Intent(requireContext(), AdverstsingPageActivity::class.java) + startActivity(intent) + requireActivity().finish() + } + ) binding.viewPager.adapter = promoAdapter - // 2) Настраиваем TabLayoutMediator, сразу задаём иконки TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, _ -> - tab.setIcon(R.drawable.tab_indicator_unselected) + tab.setIcon(com.example.projectfigma.R.drawable.tab_indicator_unselected) }.attach() - // 3) Подписываемся на смену вкладки, чтобы менять иконки binding.tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { override fun onTabSelected(tab: TabLayout.Tab) { - tab.setIcon(R.drawable.tab_indicator_selected) + tab.setIcon(com.example.projectfigma.R.drawable.tab_indicator_selected) } override fun onTabUnselected(tab: TabLayout.Tab) { - tab.setIcon(R.drawable.tab_indicator_unselected) + tab.setIcon(com.example.projectfigma.R.drawable.tab_indicator_unselected) } override fun onTabReselected(tab: TabLayout.Tab) {} }) - // 4) Тут же можете запустить автопрокрутку, если она нужна в фрагменте - val handler = Handler(Looper.getMainLooper()) - handler.postDelayed(object : Runnable { - override fun run() { + viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) { + while (isActive) { + delay(4000) if (promoAdapter.itemCount > 1) { val next = (binding.viewPager.currentItem + 1) % promoAdapter.itemCount binding.viewPager.setCurrentItem(next, true) } - handler.postDelayed(this, 4000) } - }, 4000) + } - // 5) А обновление списка (LiveData) можно тоже повесить здесь: val dao = DataBase.getDb(requireContext()).getDishesDao() dao.getBestSellers().observe(viewLifecycleOwner) { list -> promoAdapter.updateList(list) } } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - _binding = FragmentBannerFoodBinding.inflate(inflater, container, false) - return binding.root - } - override fun onDestroyView() { super.onDestroyView() _binding = null diff --git a/app/src/main/java/com/example/projectfigma/Fragments/BestSeller.kt b/app/src/main/java/com/example/projectfigma/Fragments/BestSeller.kt index a951294..e4d19ee 100644 --- a/app/src/main/java/com/example/projectfigma/Fragments/BestSeller.kt +++ b/app/src/main/java/com/example/projectfigma/Fragments/BestSeller.kt @@ -1,10 +1,15 @@ package com.example.projectfigma.Fragments +import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.TextView +import com.example.projectfigma.Activity.AdverstsingPageActivity +import com.example.projectfigma.Activity.BestSellerActivity +import com.example.projectfigma.Activity.RegActivity import com.example.projectfigma.R import com.example.projectfigma.databinding.FragmentBestSellerBinding import com.example.projectfigma.databinding.FragmentDividingLineBinding @@ -12,7 +17,7 @@ import com.example.projectfigma.databinding.FragmentDividingLineBinding class BestSeller : Fragment() { private var _binding: FragmentBestSellerBinding? = null - private val binding get() = _binding!! + private val binding get() = _binding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -24,6 +29,13 @@ class BestSeller : Fragment() { savedInstanceState: Bundle? ): View { _binding = FragmentBestSellerBinding.inflate(inflater, container, false) - return binding.root + + binding?.tvViewAll?.setOnClickListener{ + val intent = Intent(requireContext(), BestSellerActivity::class.java) + startActivity(intent) + requireActivity().finish() + } + + return binding!!.root } } \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/Fragments/BottomPanelActivity.kt b/app/src/main/java/com/example/projectfigma/Fragments/BottomPanelActivity.kt index 48a43a5..8e49e43 100644 --- a/app/src/main/java/com/example/projectfigma/Fragments/BottomPanelActivity.kt +++ b/app/src/main/java/com/example/projectfigma/Fragments/BottomPanelActivity.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import android.widget.ImageView import androidx.fragment.app.Fragment import com.example.projectfigma.Activity.FavoritesActivity +import com.example.projectfigma.Activity.FoodDetailActivity import com.example.projectfigma.Activity.HomeActivity import com.example.projectfigma.R @@ -29,8 +30,8 @@ class BottomPanelFragment : Fragment() { navHome .setOnClickListener { openActivity(HomeActivity::class.java) } navFav .setOnClickListener { openActivity(FavoritesActivity::class.java) } + navFood .setOnClickListener { openActivity(FoodDetailActivity::class.java) } /** - navFood .setOnClickListener { openActivity(FoodActivity::class.java) } navList .setOnClickListener { openActivity(OrdersActivity::class.java) } navSupport .setOnClickListener { openActivity(SupportActivity::class.java) } **/ diff --git a/app/src/main/java/com/example/projectfigma/Fragments/FavoriteListFragment.kt b/app/src/main/java/com/example/projectfigma/Fragments/FavoriteListFragment.kt index 8f55b5b..1fcb940 100644 --- a/app/src/main/java/com/example/projectfigma/Fragments/FavoriteListFragment.kt +++ b/app/src/main/java/com/example/projectfigma/Fragments/FavoriteListFragment.kt @@ -11,11 +11,13 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView + import com.example.projectfigma.Activity.FoodDetailActivity import com.example.projectfigma.Adapters.FavoriteFoodAdapter import com.example.projectfigma.DataBase.DataBase import com.example.projectfigma.Entites.Dishes import com.example.projectfigma.Entites.User import com.example.projectfigma.R + import com.example.projectfigma.Util.SwitchCard import com.example.projectfigma.databinding.FragmentBestSellerBinding import com.example.projectfigma.databinding.FragmentFavoriteListBinding import kotlinx.coroutines.Dispatchers @@ -47,7 +49,6 @@ override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - // 1) Загрузить текущего пользователя из БД lifecycleScope.launch(Dispatchers.IO) { currentUser = dataBase .getUserDao().getUserByEmail( @@ -60,21 +61,26 @@ } } private fun setupRecycler() { - adapter = FavoriteFoodAdapter(mutableListOf()) { dish -> + adapter = FavoriteFoodAdapter(mutableListOf(), + onFavoriteClick = { dish -> currentUser?.let { user -> - // 2) Удаляем ID блюда из списка val newList = user.favoriteDishesId.toMutableList() newList.remove(dish.id.toInt()) user.favoriteDishesId = newList - // 3) Сохраняем пользователя в БД и обновляем UI lifecycleScope.launch(Dispatchers.IO) { DataBase.getDb(requireContext()).getUserDao().updateUser(user) val all = DataBase.getDb(requireContext()).getDishesDao().getAll() val fav = all.filter { it.id.toInt() in newList } withContext(Dispatchers.Main) { adapter.updateList(fav) } - } - } - } + } + }}, + switchToSelfPage = { item -> + SwitchCard.switchDish( + item, + requireContext(), + FoodDetailActivity::class.java + ) + }) binding.rvFoods.layoutManager = GridLayoutManager(requireContext(), 2) binding.rvFoods.adapter = adapter } diff --git a/app/src/main/java/com/example/projectfigma/Fragments/MainBestSeller.kt b/app/src/main/java/com/example/projectfigma/Fragments/MainBestSeller.kt new file mode 100644 index 0000000..c2899f4 --- /dev/null +++ b/app/src/main/java/com/example/projectfigma/Fragments/MainBestSeller.kt @@ -0,0 +1,51 @@ +package com.example.projectfigma.Fragments + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.example.projectfigma.Activity.FoodDetailActivity +import com.example.projectfigma.Adapters.MainBestSellerAdapter +import com.example.projectfigma.DAO.DishesDao +import com.example.projectfigma.DataBase.DataBase +import com.example.projectfigma.Entites.Dishes +import com.example.projectfigma.R +import com.example.projectfigma.Util.SwitchCard + +class MainBestSeller : Fragment(R.layout.fragment_main_best_seller) { + + private lateinit var recyclerView: RecyclerView + private lateinit var adapter: MainBestSellerAdapter + private lateinit var database: DataBase + private lateinit var dishesDao: DishesDao + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + recyclerView = view.findViewById(R.id.popularRecyclerView) + recyclerView.layoutManager = GridLayoutManager(context, 2) + + database = DataBase.getDb(requireContext()) + dishesDao = database.getDishesDao() + + dishesDao.getBestSellers().observe(viewLifecycleOwner) { dishList -> + adapter = MainBestSellerAdapter(dishList, + switchToSelfPage = { item -> + SwitchCard.switchDish( + item, + requireContext(), + FoodDetailActivity::class.java + ) + } + ) + recyclerView.adapter = adapter + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/Fragments/NotificationFragment.kt b/app/src/main/java/com/example/projectfigma/Fragments/NotificationFragment.kt index 2cd7092..dc60639 100644 --- a/app/src/main/java/com/example/projectfigma/Fragments/NotificationFragment.kt +++ b/app/src/main/java/com/example/projectfigma/Fragments/NotificationFragment.kt @@ -8,6 +8,5 @@ import com.example.projectfigma.R class NotificationFragment : Fragment(R.layout.fragment_notifications) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - // TODO: здесь можно динамически заполнить список уведомлений через RecyclerView или просто оставить статично } } diff --git a/app/src/main/java/com/example/projectfigma/Fragments/RecomandationFragment.kt b/app/src/main/java/com/example/projectfigma/Fragments/RecomandationFragment.kt new file mode 100644 index 0000000..213b8e8 --- /dev/null +++ b/app/src/main/java/com/example/projectfigma/Fragments/RecomandationFragment.kt @@ -0,0 +1,47 @@ +package com.example.projectfigma.Fragments + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.View +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.example.projectfigma.Activity.FoodDetailActivity +import com.example.projectfigma.Adapters.MainBestSellerAdapter +import com.example.projectfigma.Adapters.MainRecommendAdapter +import com.example.projectfigma.DAO.DishesDao +import com.example.projectfigma.DataBase.DataBase +import com.example.projectfigma.R +import com.example.projectfigma.Util.SwitchCard + +class RecomandationFragment : Fragment(R.layout.fragment_recomandation_fragemnt) { + + private lateinit var dataBase: DataBase + private lateinit var dishesDao: DishesDao + + private val adapter by lazy { MainRecommendAdapter(emptyList(), + switchToSelfPage = { item -> + SwitchCard.switchDish( + item, + requireContext(), + FoodDetailActivity::class.java + ) + } + ) } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val rv = view.findViewById(R.id.popularRecyclerView) + rv.layoutManager = GridLayoutManager(requireContext(), 2) + rv.adapter = adapter // устанавливаем адаптер сразу + + dataBase = DataBase.getDb(requireContext()) + dishesDao = dataBase.getDishesDao() + + // Наблюдаем за списком рекомендаций + dishesDao.getRecommend().observe(viewLifecycleOwner) { dishList -> + + adapter.updateData(dishList) + adapter.notifyDataSetChanged() + } + } +} diff --git a/app/src/main/java/com/example/projectfigma/Fragments/Recommend.kt b/app/src/main/java/com/example/projectfigma/Fragments/Recommend.kt index efe1762..b73cbca 100644 --- a/app/src/main/java/com/example/projectfigma/Fragments/Recommend.kt +++ b/app/src/main/java/com/example/projectfigma/Fragments/Recommend.kt @@ -1,42 +1,61 @@ package com.example.projectfigma.Fragments +import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.TextView import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.example.projectfigma.Activity.BestSellerActivity +import com.example.projectfigma.Activity.FoodDetailActivity +import com.example.projectfigma.Activity.RecomendationActivity import com.example.projectfigma.Adapters.RecommendAdapter import com.example.projectfigma.DataBase.DataBase import com.example.projectfigma.R +import com.example.projectfigma.Util.SwitchCard import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext class Recommend : Fragment(R.layout.fragment_recommend) { + private val db by lazy { DataBase.getDb(requireContext()) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val rv = view.findViewById(R.id.rvRecommend) + val textRecomend = view.findViewById(R.id.tvHeader) rv.layoutManager = GridLayoutManager(requireContext(), 2) + textRecomend.setOnClickListener(){ + val intent = Intent(requireContext(), RecomendationActivity::class.java) + startActivity(intent) + requireActivity().finish() + } + viewLifecycleOwner.lifecycleScope.launch { - // 1. Получаем пользователя в IO val sessionEmail = db.getSessionDao().getSession()?.userEmail.orEmpty() val user = withContext(Dispatchers.IO) { db.getUserDao().getUserByEmail(sessionEmail) } - // 2. Теперь наблюдаем LiveData рекомендаций - // и каждый раз создаём новый адаптер с реальным списком withContext(Dispatchers.Main) { db.getDishesDao() .getRecommend() .observe(viewLifecycleOwner) { list -> - val adapter = RecommendAdapter(list) + val adapter = RecommendAdapter(list, + switchToSelfPage = { item -> + SwitchCard.switchDish( + item, + requireContext(), + FoodDetailActivity::class.java + ) + } + ) rv.adapter = adapter } } diff --git a/app/src/main/java/com/example/projectfigma/Util/SwitchCard.kt b/app/src/main/java/com/example/projectfigma/Util/SwitchCard.kt new file mode 100644 index 0000000..4ce9834 --- /dev/null +++ b/app/src/main/java/com/example/projectfigma/Util/SwitchCard.kt @@ -0,0 +1,21 @@ +package com.example.projectfigma.Util + +import android.content.Context +import android.content.Intent +import androidx.core.content.ContextCompat.startActivity +import androidx.viewbinding.ViewBinding +import com.example.projectfigma.Activity.FoodDetailActivity +import com.example.projectfigma.Entites.Dishes +import java.util.Objects + +class SwitchCard { + companion object { + @JvmStatic + fun switchDish(item: Dishes, context: Context, cls: Class<*>) { + val intent = Intent(context, cls).apply { + putExtra("dish", item) + } + context.startActivity(intent) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/custom_radio_button.xml b/app/src/main/res/drawable/custom_radio_button.xml new file mode 100644 index 0000000..689af94 --- /dev/null +++ b/app/src/main/res/drawable/custom_radio_button.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_add_to_card.png b/app/src/main/res/drawable/ic_add_to_card.png new file mode 100644 index 0000000..f0cd87e Binary files /dev/null and b/app/src/main/res/drawable/ic_add_to_card.png differ diff --git a/app/src/main/res/drawable/ic_badge_new.png b/app/src/main/res/drawable/ic_badge_new.png new file mode 100644 index 0000000..cb51f02 Binary files /dev/null and b/app/src/main/res/drawable/ic_badge_new.png differ diff --git a/app/src/main/res/drawable/ic_cart_for_best.png b/app/src/main/res/drawable/ic_cart_for_best.png new file mode 100644 index 0000000..03f03c2 Binary files /dev/null and b/app/src/main/res/drawable/ic_cart_for_best.png differ diff --git a/app/src/main/res/drawable/ic_heart_in_circle.png b/app/src/main/res/drawable/ic_heart_in_circle.png new file mode 100644 index 0000000..49217e6 Binary files /dev/null and b/app/src/main/res/drawable/ic_heart_in_circle.png differ diff --git a/app/src/main/res/drawable/ic_nachosi.png b/app/src/main/res/drawable/ic_nachosi.png new file mode 100644 index 0000000..8992fe8 Binary files /dev/null and b/app/src/main/res/drawable/ic_nachosi.png differ diff --git a/app/src/main/res/drawable/into_best_seller1.png b/app/src/main/res/drawable/into_best_seller1.png new file mode 100644 index 0000000..d310b39 Binary files /dev/null and b/app/src/main/res/drawable/into_best_seller1.png differ diff --git a/app/src/main/res/drawable/into_best_seller2.png b/app/src/main/res/drawable/into_best_seller2.png new file mode 100644 index 0000000..e2b68ed Binary files /dev/null and b/app/src/main/res/drawable/into_best_seller2.png differ diff --git a/app/src/main/res/drawable/into_best_seller3.png b/app/src/main/res/drawable/into_best_seller3.png new file mode 100644 index 0000000..c1e7a11 Binary files /dev/null and b/app/src/main/res/drawable/into_best_seller3.png differ diff --git a/app/src/main/res/drawable/into_best_seller4.png b/app/src/main/res/drawable/into_best_seller4.png new file mode 100644 index 0000000..54e8634 Binary files /dev/null and b/app/src/main/res/drawable/into_best_seller4.png differ diff --git a/app/src/main/res/drawable/into_best_seller5.png b/app/src/main/res/drawable/into_best_seller5.png new file mode 100644 index 0000000..0acf1bc Binary files /dev/null and b/app/src/main/res/drawable/into_best_seller5.png differ diff --git a/app/src/main/res/drawable/into_best_seller6.png b/app/src/main/res/drawable/into_best_seller6.png new file mode 100644 index 0000000..c4e5938 Binary files /dev/null and b/app/src/main/res/drawable/into_best_seller6.png differ diff --git a/app/src/main/res/drawable/radio_checked.xml b/app/src/main/res/drawable/radio_checked.xml new file mode 100644 index 0000000..f365734 --- /dev/null +++ b/app/src/main/res/drawable/radio_checked.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/radio_unchecked.xml b/app/src/main/res/drawable/radio_unchecked.xml new file mode 100644 index 0000000..500afdf --- /dev/null +++ b/app/src/main/res/drawable/radio_unchecked.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable/rounded_corners.xml b/app/src/main/res/drawable/rounded_corners.xml new file mode 100644 index 0000000..151f366 --- /dev/null +++ b/app/src/main/res/drawable/rounded_corners.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_advertising_page.xml b/app/src/main/res/layout/activity_advertising_page.xml index 565c290..9fe3f0c 100644 --- a/app/src/main/res/layout/activity_advertising_page.xml +++ b/app/src/main/res/layout/activity_advertising_page.xml @@ -1,13 +1,57 @@ + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/background"> + + + + + + + + + + + - + + app:layout_constraintTop_toBottomOf="@+id/constraintLayoutHeader"> - - + + + android:textSize="25dp" /> - - + + + + android:textSize="18dp" + android:textStyle="bold" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.086" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/dividingLine2" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/app/src/main/res/layout/activity_best_seller.xml b/app/src/main/res/layout/activity_best_seller.xml new file mode 100644 index 0000000..3bf586e --- /dev/null +++ b/app/src/main/res/layout/activity_best_seller.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_food_detail.xml b/app/src/main/res/layout/activity_food_detail.xml new file mode 100644 index 0000000..c1aefc5 --- /dev/null +++ b/app/src/main/res/layout/activity_food_detail.xml @@ -0,0 +1,479 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index afd1818..7c1ebb4 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -87,6 +87,9 @@ + + + + app:layout_constraintTop_toBottomOf="@+id/constraintLayout" + app:layout_constraintVertical_bias="0.666"> - + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_main_best_seller.xml b/app/src/main/res/layout/fragment_main_best_seller.xml new file mode 100644 index 0000000..dc800e2 --- /dev/null +++ b/app/src/main/res/layout/fragment_main_best_seller.xml @@ -0,0 +1,36 @@ + + + + + + + + diff --git a/app/src/main/res/layout/fragment_recomandation_fragemnt.xml b/app/src/main/res/layout/fragment_recomandation_fragemnt.xml new file mode 100644 index 0000000..d8b1d4d --- /dev/null +++ b/app/src/main/res/layout/fragment_recomandation_fragemnt.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + /> + + + + + diff --git a/app/src/main/res/layout/item_banner.xml b/app/src/main/res/layout/item_banner.xml index 2cd74b0..ed9debb 100644 --- a/app/src/main/res/layout/item_banner.xml +++ b/app/src/main/res/layout/item_banner.xml @@ -1,5 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_food.xml b/app/src/main/res/layout/item_food.xml index e5ea760..29d627e 100644 --- a/app/src/main/res/layout/item_food.xml +++ b/app/src/main/res/layout/item_food.xml @@ -39,11 +39,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="5.0" - android:textColor="@android:color/white" + android:textColor="@android:color/black" android:textSize="12sp" android:layout_marginStart="4dp"/> diff --git a/app/src/main/res/layout/item_main_recomend.xml b/app/src/main/res/layout/item_main_recomend.xml new file mode 100644 index 0000000..e51529d --- /dev/null +++ b/app/src/main/res/layout/item_main_recomend.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_new_recomend.xml b/app/src/main/res/layout/item_new_recomend.xml new file mode 100644 index 0000000..5982d36 --- /dev/null +++ b/app/src/main/res/layout/item_new_recomend.xml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 1eb1848..8ee1ec4 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -17,4 +17,34 @@ @drawable/indicator_selected + + + + + + + + + + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 685f141..0bc321c 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,14 +1,20 @@