From d192568ed8481468d9817d564e657044dfbcf24a Mon Sep 17 00:00:00 2001
From: 230409 <230409@epvc.pt>
Date: Tue, 9 Jun 2026 17:12:07 +0100
Subject: [PATCH] 9/06
---
app/src/main/AndroidManifest.xml | 9 ++
.../pap_teste/ClientDashboardActivity.java | 115 ++++++------------
.../com/example/pap_teste/MainActivity.java | 9 +-
.../res/layout/activity_client_dashboard.xml | 48 +-------
app/src/main/res/values/themes.xml | 21 ++++
5 files changed, 81 insertions(+), 121 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b1b9e33..4fe3ffb 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -14,6 +14,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/example/pap_teste/ClientDashboardActivity.java b/app/src/main/java/com/example/pap_teste/ClientDashboardActivity.java
index 1b2efa1..a0ca362 100644
--- a/app/src/main/java/com/example/pap_teste/ClientDashboardActivity.java
+++ b/app/src/main/java/com/example/pap_teste/ClientDashboardActivity.java
@@ -37,19 +37,17 @@ public class ClientDashboardActivity extends AppCompatActivity {
private TextView txtGreeting;
private ImageView imgProfile;
private EditText etSearch;
- private ChipGroup chipGroupCategories;
- private RecyclerView rvFeatured, rvMainRestaurants;
+ private RecyclerView rvFeatured;
private ProgressBar progressBar;
- private View layoutFeatured, layoutAllRestaurants;
+ private View layoutFeatured;
+ private android.widget.LinearLayout categoriesContainer;
private List allRestaurants = new ArrayList<>();
private List filteredRestaurants = new ArrayList<>();
- private RestaurantAdapter mainAdapter;
private FeaturedRestaurantAdapter featuredAdapter;
- private final String[] CATEGORIES = { "Tudo", "Carnes", "Massas", "Sushi", "Pizzas", "Sobremesas" };
- private String currentCategoryFilter = "Tudo";
+ private final String[] CATEGORIES = { "Carnes", "Massas", "Sushi", "Pizzas", "Sobremesas" };
private String currentSearchFilter = "";
@Override
@@ -70,43 +68,38 @@ public class ClientDashboardActivity extends AppCompatActivity {
initViews();
setupBottomNavigation();
setupSearch();
- setupCategories();
updateGreeting();
fetchProfilePicture();
fetchRestaurants();
+
+ // Iniciar serviço de notificações se for Android O ou superior
+ Intent serviceIntent = new Intent(this, ReservationNotificationService.class);
+ startService(serviceIntent);
}
+ private RestaurantAdapter.OnRestaurantClickListener clickListener;
+
private void initViews() {
txtGreeting = findViewById(R.id.txtClientGreeting);
imgProfile = findViewById(R.id.imgProfile);
etSearch = findViewById(R.id.etSearch);
- chipGroupCategories = findViewById(R.id.chipGroupCategories);
rvFeatured = findViewById(R.id.rvFeatured);
- rvMainRestaurants = findViewById(R.id.rvMainRestaurants);
progressBar = findViewById(R.id.progressBar);
layoutFeatured = findViewById(R.id.layoutFeatured);
- layoutAllRestaurants = findViewById(R.id.layoutAllRestaurants);
+ categoriesContainer = findViewById(R.id.categoriesContainer);
rvFeatured.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
- rvMainRestaurants.setLayoutManager(new LinearLayoutManager(this));
// Click listener for restaurants to open booking flow
- RestaurantAdapter.OnRestaurantClickListener clickListener = restaurant -> {
+ clickListener = restaurant -> {
Intent intent = new Intent(this, ExplorarRestaurantesActivity.class);
- // Reusing existing activity for details if needed, or pass data to
- // NovaReservaActivity
- // We pass the filter so it can maybe open directly or we just pass restaurant
- // email
intent.putExtra("restaurant", restaurant);
startActivity(intent);
};
featuredAdapter = new FeaturedRestaurantAdapter(new ArrayList<>(), clickListener);
- mainAdapter = new RestaurantAdapter(filteredRestaurants, clickListener);
-
rvFeatured.setAdapter(featuredAdapter);
- rvMainRestaurants.setAdapter(mainAdapter);
// Click listener for profile picture in the header
findViewById(R.id.cardProfile).setOnClickListener(v -> {
@@ -163,7 +156,7 @@ public class ClientDashboardActivity extends AppCompatActivity {
private void fetchRestaurants() {
progressBar.setVisibility(View.VISIBLE);
layoutFeatured.setVisibility(View.GONE);
- layoutAllRestaurants.setVisibility(View.GONE);
+ categoriesContainer.removeAllViews();
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("Restaurantes");
usersRef.addValueEventListener(new ValueEventListener() {
@@ -207,47 +200,6 @@ public class ClientDashboardActivity extends AppCompatActivity {
});
}
- private void setupCategories() {
- for (String category : CATEGORIES) {
- Chip chip = new Chip(this);
- chip.setText(category);
- chip.setCheckable(true);
- chip.setClickable(true);
- // Default styling
- chip.setChipBackgroundColorResource(R.color.colorSurface);
- chip.setTextColor(getResources().getColor(R.color.colorTextSecondary));
- chip.setChipStrokeWidth(0f);
-
- if (category.equals("Tudo")) {
- chip.setChecked(true);
- chip.setChipBackgroundColorResource(R.color.colorPrimary);
- chip.setTextColor(getResources().getColor(R.color.white));
- }
-
- chip.setOnCheckedChangeListener((buttonView, isChecked) -> {
- if (isChecked) {
- // Reset all other chips visual state
- for (int i = 0; i < chipGroupCategories.getChildCount(); i++) {
- Chip c = (Chip) chipGroupCategories.getChildAt(i);
- if (c != chip) {
- c.setChipBackgroundColorResource(R.color.colorSurface);
- c.setTextColor(getResources().getColor(R.color.colorTextSecondary));
- }
- }
- chip.setChipBackgroundColorResource(R.color.colorPrimary);
- chip.setTextColor(getResources().getColor(R.color.white));
-
- currentCategoryFilter = category;
- applyFilters();
- } else if (currentCategoryFilter.equals(category)) {
- // Prevent unchecking the currently selected chip
- chip.setChecked(true);
- }
- });
- chipGroupCategories.addView(chip);
- }
- }
-
private void setupSearch() {
etSearch.addTextChangedListener(new TextWatcher() {
@Override
@@ -271,35 +223,46 @@ public class ClientDashboardActivity extends AppCompatActivity {
String normalizedSearch = normalizeString(currentSearchFilter);
for (Restaurant r : allRestaurants) {
- boolean matchesCategory = currentCategoryFilter.equals("Tudo")
- || currentCategoryFilter.equals(r.getCategory());
-
String normalizedName = normalizeString(r.getName());
boolean matchesSearch = currentSearchFilter.isEmpty() || normalizedName.contains(normalizedSearch);
- if (matchesCategory && matchesSearch) {
+ if (matchesSearch) {
filteredRestaurants.add(r);
}
}
- mainAdapter.notifyDataSetChanged();
-
- // Update featured (just the first 3 for demo, or based on a specific logic)
+ // Update featured carousel with top restaurants
List featuredList = new ArrayList<>();
for (int i = 0; i < Math.min(3, filteredRestaurants.size()); i++) {
featuredList.add(filteredRestaurants.get(i));
}
- featuredAdapter = new FeaturedRestaurantAdapter(featuredList,
- mainAdapter instanceof RestaurantAdapter ? restaurant -> {
- Intent intent = new Intent(this, ExplorarRestaurantesActivity.class);
- intent.putExtra("restaurant", restaurant);
- startActivity(intent);
- } : null);
+ featuredAdapter = new FeaturedRestaurantAdapter(featuredList, clickListener);
rvFeatured.setAdapter(featuredAdapter);
-
layoutFeatured.setVisibility(featuredList.isEmpty() ? View.GONE : View.VISIBLE);
- layoutAllRestaurants.setVisibility(filteredRestaurants.isEmpty() ? View.GONE : View.VISIBLE);
+
+ // Update category rows
+ categoriesContainer.removeAllViews();
+ for (String category : CATEGORIES) {
+ List catList = new ArrayList<>();
+ for (Restaurant r : filteredRestaurants) {
+ if (category.equals(r.getCategory())) {
+ catList.add(r);
+ }
+ }
+
+ if (!catList.isEmpty()) {
+ View rowView = android.view.LayoutInflater.from(this).inflate(R.layout.item_category_row, categoriesContainer, false);
+ TextView txtTitle = rowView.findViewById(R.id.txtCategoryTitle);
+ RecyclerView rvCategory = rowView.findViewById(R.id.rvCategoryRestaurants);
+
+ txtTitle.setText(category);
+ rvCategory.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
+ rvCategory.setAdapter(new FeaturedRestaurantAdapter(catList, clickListener));
+
+ categoriesContainer.addView(rowView);
+ }
+ }
}
private String normalizeString(String str) {
diff --git a/app/src/main/java/com/example/pap_teste/MainActivity.java b/app/src/main/java/com/example/pap_teste/MainActivity.java
index cfe884a..c9f71cd 100644
--- a/app/src/main/java/com/example/pap_teste/MainActivity.java
+++ b/app/src/main/java/com/example/pap_teste/MainActivity.java
@@ -160,12 +160,19 @@ public class MainActivity extends AppCompatActivity {
permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
}
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ if (ContextCompat.checkSelfPermission(this,
+ Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
+ permissionsNeeded.add(Manifest.permission.POST_NOTIFICATIONS);
+ }
+ }
if (!permissionsNeeded.isEmpty()) {
new AlertDialog.Builder(this)
.setTitle("Permissões Necessárias")
.setMessage(
- "Para o correto funcionamento do check-in, serviços de proximidade e fotos da galeria, precisamos de algumas permissões.")
+ "Para o correto funcionamento do check-in, receber notificações de reservas e acesso a fotos, precisamos de algumas permissões.")
.setPositiveButton("Configurar", (dialog, which) -> {
permissionRequest.launch(permissionsNeeded.toArray(new String[0]));
})
diff --git a/app/src/main/res/layout/activity_client_dashboard.xml b/app/src/main/res/layout/activity_client_dashboard.xml
index 1789a35..050c90e 100644
--- a/app/src/main/res/layout/activity_client_dashboard.xml
+++ b/app/src/main/res/layout/activity_client_dashboard.xml
@@ -112,24 +112,6 @@
-
-
-
-
-
-
-
-
+
-
-
-
-
-
+ android:layout_marginTop="8dp"
+ android:paddingBottom="16dp" />
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index d260148..67d6814 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -14,7 +14,28 @@
- sans-serif
+
+
+ - @style/ShapeAppearance.App.SmallComponent
+ - @style/ShapeAppearance.App.MediumComponent
+ - @style/ShapeAppearance.App.LargeComponent
+
+
+
+
+
+
+
\ No newline at end of file