This commit is contained in:
2026-04-30 17:43:08 +01:00
parent cd5ffb3b43
commit dd8a80ca2e
14 changed files with 334 additions and 197 deletions

1
.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
Pap_teste

View File

@@ -98,16 +98,18 @@ public class CheckInAntecipadoActivity extends AppCompatActivity implements Loca
} }
private boolean hasRequiredPermissions() { private boolean hasRequiredPermissions() {
boolean fineLocation = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; boolean fineLocation = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
boolean btScan = ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED; boolean btScan = ActivityCompat.checkSelfPermission(this,
Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED;
return fineLocation && btScan; return fineLocation && btScan;
} }
return fineLocation; return fineLocation;
} }
private void loadRestaurantSettings(String restaurantId) { private void loadRestaurantSettings(String restaurantId) {
databaseReference = FirebaseDatabase.getInstance().getReference().child("users").child(restaurantId); databaseReference = FirebaseDatabase.getInstance().getReference().child("Restaurantes").child(restaurantId);
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() { databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override @Override
public void onDataChange(@NonNull DataSnapshot snapshot) { public void onDataChange(@NonNull DataSnapshot snapshot) {
@@ -161,7 +163,8 @@ public class CheckInAntecipadoActivity extends AppCompatActivity implements Loca
} }
private void startLocationUpdates() { private void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return; return;
} }
try { try {

View File

@@ -44,11 +44,11 @@ public class ClientDashboardActivity extends AppCompatActivity {
private List<Restaurant> allRestaurants = new ArrayList<>(); private List<Restaurant> allRestaurants = new ArrayList<>();
private List<Restaurant> filteredRestaurants = new ArrayList<>(); private List<Restaurant> filteredRestaurants = new ArrayList<>();
private RestaurantAdapter mainAdapter; private RestaurantAdapter mainAdapter;
private FeaturedRestaurantAdapter featuredAdapter; private FeaturedRestaurantAdapter featuredAdapter;
private final String[] CATEGORIES = {"Tudo", "Carnes", "Massas", "Sushi", "Pizzas", "Sobremesas"}; private final String[] CATEGORIES = { "Tudo", "Carnes", "Massas", "Sushi", "Pizzas", "Sobremesas" };
private String currentCategoryFilter = "Tudo"; private String currentCategoryFilter = "Tudo";
private String currentSearchFilter = ""; private String currentSearchFilter = "";
@@ -57,7 +57,7 @@ public class ClientDashboardActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
EdgeToEdge.enable(this); EdgeToEdge.enable(this);
setContentView(R.layout.activity_client_dashboard); setContentView(R.layout.activity_client_dashboard);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.clientRoot), (v, insets) -> { ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.clientRoot), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
@@ -71,7 +71,7 @@ public class ClientDashboardActivity extends AppCompatActivity {
setupBottomNavigation(); setupBottomNavigation();
setupSearch(); setupSearch();
setupCategories(); setupCategories();
updateGreeting(); updateGreeting();
fetchProfilePicture(); fetchProfilePicture();
fetchRestaurants(); fetchRestaurants();
@@ -94,15 +94,17 @@ public class ClientDashboardActivity extends AppCompatActivity {
// Click listener for restaurants to open booking flow // Click listener for restaurants to open booking flow
RestaurantAdapter.OnRestaurantClickListener clickListener = restaurant -> { RestaurantAdapter.OnRestaurantClickListener clickListener = restaurant -> {
Intent intent = new Intent(this, ExplorarRestaurantesActivity.class); Intent intent = new Intent(this, ExplorarRestaurantesActivity.class);
// Reusing existing activity for details if needed, or pass data to NovaReservaActivity // Reusing existing activity for details if needed, or pass data to
// We pass the filter so it can maybe open directly or we just pass restaurant email // NovaReservaActivity
// We pass the filter so it can maybe open directly or we just pass restaurant
// email
intent.putExtra("category_filter", restaurant.getCategory()); intent.putExtra("category_filter", restaurant.getCategory());
startActivity(intent); startActivity(intent);
}; };
featuredAdapter = new FeaturedRestaurantAdapter(new ArrayList<>(), clickListener); featuredAdapter = new FeaturedRestaurantAdapter(new ArrayList<>(), clickListener);
mainAdapter = new RestaurantAdapter(filteredRestaurants, clickListener); mainAdapter = new RestaurantAdapter(filteredRestaurants, clickListener);
rvFeatured.setAdapter(featuredAdapter); rvFeatured.setAdapter(featuredAdapter);
rvMainRestaurants.setAdapter(mainAdapter); rvMainRestaurants.setAdapter(mainAdapter);
@@ -146,14 +148,16 @@ public class ClientDashboardActivity extends AppCompatActivity {
} }
private void fetchProfilePicture() { private void fetchProfilePicture() {
if (email == null) return; if (email == null)
return;
String documentId = email.replace(".", "_").replace("@", "_at_"); String documentId = email.replace(".", "_").replace("@", "_at_");
FirebaseDatabase.getInstance().getReference().child("users").child(documentId).child("photoUrl") FirebaseDatabase.getInstance().getReference().child("Clientes").child(documentId).child("photoUrl")
.get().addOnSuccessListener(snapshot -> { .get().addOnSuccessListener(snapshot -> {
if (!isDestroyed() && snapshot.exists() && snapshot.getValue(String.class) != null) { if (!isDestroyed() && snapshot.exists() && snapshot.getValue(String.class) != null) {
com.bumptech.glide.Glide.with(this).load(snapshot.getValue(String.class)).circleCrop().into(imgProfile); com.bumptech.glide.Glide.with(this).load(snapshot.getValue(String.class)).circleCrop()
} .into(imgProfile);
}); }
});
} }
private void fetchRestaurants() { private void fetchRestaurants() {
@@ -161,7 +165,7 @@ public class ClientDashboardActivity extends AppCompatActivity {
layoutFeatured.setVisibility(View.GONE); layoutFeatured.setVisibility(View.GONE);
layoutAllRestaurants.setVisibility(View.GONE); layoutAllRestaurants.setVisibility(View.GONE);
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("users"); DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("Restaurantes");
usersRef.addListenerForSingleValueEvent(new ValueEventListener() { usersRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override @Override
public void onDataChange(@androidx.annotation.NonNull DataSnapshot snapshot) { public void onDataChange(@androidx.annotation.NonNull DataSnapshot snapshot) {
@@ -171,20 +175,23 @@ public class ClientDashboardActivity extends AppCompatActivity {
for (DataSnapshot ds : snapshot.getChildren()) { for (DataSnapshot ds : snapshot.getChildren()) {
String role = ds.child("role").getValue(String.class); String role = ds.child("role").getValue(String.class);
String accountType = ds.child("accountType").getValue(String.class); String accountType = ds.child("accountType").getValue(String.class);
if ("ADMIN".equalsIgnoreCase(role) || "ESTABELECIMENTO".equalsIgnoreCase(accountType)) { if ("ADMIN".equalsIgnoreCase(role) || "ESTABELECIMENTO".equalsIgnoreCase(accountType)) {
String name = ds.child("establishmentName").getValue(String.class); String name = ds.child("establishmentName").getValue(String.class);
if (name == null) name = ds.child("displayName").getValue(String.class); if (name == null)
name = ds.child("displayName").getValue(String.class);
String email = ds.child("email").getValue(String.class); String email = ds.child("email").getValue(String.class);
String cat = ds.child("category").getValue(String.class); String cat = ds.child("category").getValue(String.class);
String logoUrl = ds.child("logoUrl").getValue(String.class); String logoUrl = ds.child("logoUrl").getValue(String.class);
Double ratingAvg = ds.child("ratingAvg").getValue(Double.class); Double ratingAvg = ds.child("ratingAvg").getValue(Double.class);
Integer ratingCount = ds.child("ratingCount").getValue(Integer.class); Integer ratingCount = ds.child("ratingCount").getValue(Integer.class);
if (name != null && email != null) { if (name != null && email != null) {
Restaurant r = new Restaurant(name, cat != null ? cat : "Vário", email, false, logoUrl); Restaurant r = new Restaurant(name, cat != null ? cat : "Vário", email, false, logoUrl);
if (ratingAvg != null) r.setRatingAvg(ratingAvg); if (ratingAvg != null)
if (ratingCount != null) r.setRatingCount(ratingCount); r.setRatingAvg(ratingAvg);
if (ratingCount != null)
r.setRatingCount(ratingCount);
allRestaurants.add(r); allRestaurants.add(r);
} }
} }
@@ -209,13 +216,13 @@ public class ClientDashboardActivity extends AppCompatActivity {
chip.setChipBackgroundColorResource(R.color.colorSurface); chip.setChipBackgroundColorResource(R.color.colorSurface);
chip.setTextColor(getResources().getColor(R.color.colorTextSecondary)); chip.setTextColor(getResources().getColor(R.color.colorTextSecondary));
chip.setChipStrokeWidth(0f); chip.setChipStrokeWidth(0f);
if (category.equals("Tudo")) { if (category.equals("Tudo")) {
chip.setChecked(true); chip.setChecked(true);
chip.setChipBackgroundColorResource(R.color.colorPrimary); chip.setChipBackgroundColorResource(R.color.colorPrimary);
chip.setTextColor(getResources().getColor(R.color.white)); chip.setTextColor(getResources().getColor(R.color.white));
} }
chip.setOnCheckedChangeListener((buttonView, isChecked) -> { chip.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (isChecked) { if (isChecked) {
// Reset all other chips visual state // Reset all other chips visual state
@@ -228,7 +235,7 @@ public class ClientDashboardActivity extends AppCompatActivity {
} }
chip.setChipBackgroundColorResource(R.color.colorPrimary); chip.setChipBackgroundColorResource(R.color.colorPrimary);
chip.setTextColor(getResources().getColor(R.color.white)); chip.setTextColor(getResources().getColor(R.color.white));
currentCategoryFilter = category; currentCategoryFilter = category;
applyFilters(); applyFilters();
} else if (currentCategoryFilter.equals(category)) { } else if (currentCategoryFilter.equals(category)) {
@@ -243,7 +250,8 @@ public class ClientDashboardActivity extends AppCompatActivity {
private void setupSearch() { private void setupSearch() {
etSearch.addTextChangedListener(new TextWatcher() { etSearch.addTextChangedListener(new TextWatcher() {
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override @Override
public void onTextChanged(CharSequence s, int start, int before, int count) { public void onTextChanged(CharSequence s, int start, int before, int count) {
@@ -252,47 +260,50 @@ public class ClientDashboardActivity extends AppCompatActivity {
} }
@Override @Override
public void afterTextChanged(Editable s) {} public void afterTextChanged(Editable s) {
}
}); });
} }
private void applyFilters() { private void applyFilters() {
filteredRestaurants.clear(); filteredRestaurants.clear();
String normalizedSearch = normalizeString(currentSearchFilter); String normalizedSearch = normalizeString(currentSearchFilter);
for (Restaurant r : allRestaurants) { for (Restaurant r : allRestaurants) {
boolean matchesCategory = currentCategoryFilter.equals("Tudo") || currentCategoryFilter.equals(r.getCategory()); boolean matchesCategory = currentCategoryFilter.equals("Tudo")
|| currentCategoryFilter.equals(r.getCategory());
String normalizedName = normalizeString(r.getName()); String normalizedName = normalizeString(r.getName());
boolean matchesSearch = currentSearchFilter.isEmpty() || normalizedName.contains(normalizedSearch); boolean matchesSearch = currentSearchFilter.isEmpty() || normalizedName.contains(normalizedSearch);
if (matchesCategory && matchesSearch) { if (matchesCategory && matchesSearch) {
filteredRestaurants.add(r); filteredRestaurants.add(r);
} }
} }
mainAdapter.notifyDataSetChanged(); mainAdapter.notifyDataSetChanged();
// Update featured (just the first 3 for demo, or based on a specific logic) // Update featured (just the first 3 for demo, or based on a specific logic)
List<Restaurant> featuredList = new ArrayList<>(); List<Restaurant> featuredList = new ArrayList<>();
for (int i = 0; i < Math.min(3, filteredRestaurants.size()); i++) { for (int i = 0; i < Math.min(3, filteredRestaurants.size()); i++) {
featuredList.add(filteredRestaurants.get(i)); featuredList.add(filteredRestaurants.get(i));
} }
featuredAdapter = new FeaturedRestaurantAdapter(featuredList, mainAdapter instanceof RestaurantAdapter ? featuredAdapter = new FeaturedRestaurantAdapter(featuredList,
restaurant -> { mainAdapter instanceof RestaurantAdapter ? restaurant -> {
Intent intent = new Intent(this, ExplorarRestaurantesActivity.class); Intent intent = new Intent(this, ExplorarRestaurantesActivity.class);
intent.putExtra("category_filter", restaurant.getCategory()); intent.putExtra("category_filter", restaurant.getCategory());
startActivity(intent); startActivity(intent);
} : null); } : null);
rvFeatured.setAdapter(featuredAdapter); rvFeatured.setAdapter(featuredAdapter);
layoutFeatured.setVisibility(featuredList.isEmpty() ? View.GONE : View.VISIBLE); layoutFeatured.setVisibility(featuredList.isEmpty() ? View.GONE : View.VISIBLE);
layoutAllRestaurants.setVisibility(filteredRestaurants.isEmpty() ? View.GONE : View.VISIBLE); layoutAllRestaurants.setVisibility(filteredRestaurants.isEmpty() ? View.GONE : View.VISIBLE);
} }
private String normalizeString(String str) { private String normalizeString(String str) {
if (str == null) return ""; if (str == null)
return "";
// Remove accents and special marks, and convert to lowercase // Remove accents and special marks, and convert to lowercase
String normalized = java.text.Normalizer.normalize(str, java.text.Normalizer.Form.NFD); String normalized = java.text.Normalizer.normalize(str, java.text.Normalizer.Form.NFD);
normalized = normalized.replaceAll("\\p{InCombiningDiacriticalMarks}+", ""); normalized = normalized.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");

View File

@@ -59,7 +59,7 @@ public class DefinicoesAdminActivity extends AppCompatActivity {
documentId = email.replace(".", "_").replace("@", "_at_"); documentId = email.replace(".", "_").replace("@", "_at_");
} }
databaseReference = FirebaseDatabase.getInstance().getReference().child("users"); databaseReference = FirebaseDatabase.getInstance().getReference().child("Restaurantes");
inputRadius = findViewById(R.id.inputRadius); inputRadius = findViewById(R.id.inputRadius);
inputAddress = findViewById(R.id.inputAddress); inputAddress = findViewById(R.id.inputAddress);

View File

@@ -42,8 +42,13 @@ public class DetalhesReservasActivity extends AppCompatActivity {
}); });
restaurantEmail = getIntent().getStringExtra(MainActivity.EXTRA_EMAIL); restaurantEmail = getIntent().getStringExtra(MainActivity.EXTRA_EMAIL);
if (restaurantEmail == null) if (restaurantEmail == null) {
restaurantEmail = "sabor_arte@restaurante.com"; if (com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null) {
restaurantEmail = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser().getEmail();
} else {
restaurantEmail = "sabor_arte@restaurante.com";
}
}
bindViews(); bindViews();
setupList(); setupList();

View File

@@ -46,27 +46,49 @@ public class EstablishmentDashboardActivity extends AppCompatActivity {
Button btnSettings = findViewById(R.id.btnDefinicoes); Button btnSettings = findViewById(R.id.btnDefinicoes);
Button btnBack = findViewById(R.id.btnVoltar); Button btnBack = findViewById(R.id.btnVoltar);
btnOpenWalkIns.setOnClickListener(v -> startActivity(new Intent(this, ListaEsperaActivity.class))); String email = getIntent().getStringExtra(MainActivity.EXTRA_EMAIL);
if (email == null) {
if (com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null) {
email = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser().getEmail();
} else {
return; // Can't proceed without email
}
}
final String finalEmail = email;
btnStaff.setOnClickListener(v -> startActivity(new Intent(this, GestaoStaffActivity.class))); btnOpenWalkIns.setOnClickListener(v -> {
Intent intent = new Intent(this, ListaEsperaActivity.class);
intent.putExtra(MainActivity.EXTRA_EMAIL, finalEmail);
startActivity(intent);
});
btnGerirMesas.setOnClickListener(v -> startActivity(new Intent(this, GerirMesasActivity.class))); btnStaff.setOnClickListener(v -> {
Intent intent = new Intent(this, GestaoStaffActivity.class);
intent.putExtra(MainActivity.EXTRA_EMAIL, finalEmail);
startActivity(intent);
});
btnGerirMesas.setOnClickListener(v -> {
Intent intent = new Intent(this, GerirMesasActivity.class);
intent.putExtra(MainActivity.EXTRA_EMAIL, finalEmail);
startActivity(intent);
});
btnDetails.setOnClickListener(v -> { btnDetails.setOnClickListener(v -> {
Intent intent = new Intent(this, DetalhesReservasActivity.class); Intent intent = new Intent(this, DetalhesReservasActivity.class);
intent.putExtra(MainActivity.EXTRA_EMAIL, getIntent().getStringExtra(MainActivity.EXTRA_EMAIL)); intent.putExtra(MainActivity.EXTRA_EMAIL, finalEmail);
startActivity(intent); startActivity(intent);
}); });
btnSettings.setOnClickListener(v -> { btnSettings.setOnClickListener(v -> {
Intent intent = new Intent(this, DefinicoesAdminActivity.class); Intent intent = new Intent(this, DefinicoesAdminActivity.class);
intent.putExtra(MainActivity.EXTRA_EMAIL, getIntent().getStringExtra(MainActivity.EXTRA_EMAIL)); intent.putExtra(MainActivity.EXTRA_EMAIL, finalEmail);
startActivity(intent); startActivity(intent);
}); });
findViewById(R.id.cardReservasHoje).setOnClickListener(v -> { findViewById(R.id.cardReservasHoje).setOnClickListener(v -> {
Intent intent = new Intent(this, DetalhesReservasActivity.class); Intent intent = new Intent(this, DetalhesReservasActivity.class);
intent.putExtra(MainActivity.EXTRA_EMAIL, getIntent().getStringExtra(MainActivity.EXTRA_EMAIL)); intent.putExtra(MainActivity.EXTRA_EMAIL, finalEmail);
startActivity(intent); startActivity(intent);
}); });

View File

@@ -38,7 +38,6 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
} }
}); });
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@@ -89,23 +88,26 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
} }
private void loadRestaurantRating() { private void loadRestaurantRating() {
if (selectedRestaurant == null || selectedRestaurant.getEmail() == null) return; if (selectedRestaurant == null || selectedRestaurant.getEmail() == null)
return;
String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_"); String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_");
android.widget.TextView txtAvgRating = findViewById(R.id.txtAvgRating); android.widget.TextView txtAvgRating = findViewById(R.id.txtAvgRating);
android.widget.TextView txtTotalReviews = findViewById(R.id.txtTotalReviews); android.widget.TextView txtTotalReviews = findViewById(R.id.txtTotalReviews);
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("users") com.google.firebase.database.FirebaseDatabase.getInstance().getReference("Restaurantes")
.child(encodedEmail) .child(encodedEmail)
.addValueEventListener(new com.google.firebase.database.ValueEventListener() { .addValueEventListener(new com.google.firebase.database.ValueEventListener() {
@Override @Override
public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) { public void onDataChange(
@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) {
Double avg = snapshot.child("ratingAvg").getValue(Double.class); Double avg = snapshot.child("ratingAvg").getValue(Double.class);
Integer count = snapshot.child("ratingCount").getValue(Integer.class); Integer count = snapshot.child("ratingCount").getValue(Integer.class);
if (avg != null && count != null && count > 0) { if (avg != null && count != null && count > 0) {
txtAvgRating.setText(String.format(java.util.Locale.getDefault(), "%.1f", avg)); txtAvgRating.setText(String.format(java.util.Locale.getDefault(), "%.1f", avg));
txtTotalReviews.setText(String.format(java.util.Locale.getDefault(), "(%d avaliações)", count)); txtTotalReviews
.setText(String.format(java.util.Locale.getDefault(), "(%d avaliações)", count));
} else { } else {
txtAvgRating.setText("0.0"); txtAvgRating.setText("0.0");
txtTotalReviews.setText("(0 avaliações)"); txtTotalReviews.setText("(0 avaliações)");
@@ -113,44 +115,51 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
} }
@Override @Override
public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {} public void onCancelled(
@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {
}
}); });
} }
private void setupRestaurantList() { private void setupRestaurantList() {
String filter = getIntent().getStringExtra("category_filter"); String filter = getIntent().getStringExtra("category_filter");
java.util.List<com.example.pap_teste.models.Restaurant> restaurantsList = new java.util.ArrayList<>(); java.util.List<com.example.pap_teste.models.Restaurant> restaurantsList = new java.util.ArrayList<>();
com.google.firebase.database.DatabaseReference usersRef = com.google.firebase.database.FirebaseDatabase.getInstance().getReference("users"); com.google.firebase.database.DatabaseReference usersRef = com.google.firebase.database.FirebaseDatabase
.getInstance().getReference("Restaurantes");
com.google.firebase.database.Query query = usersRef; com.google.firebase.database.Query query = usersRef;
if (filter != null) { if (filter != null) {
query = usersRef.orderByChild("category").equalTo(filter); query = usersRef.orderByChild("category").equalTo(filter);
} }
if (progressBar != null) progressBar.setVisibility(android.view.View.VISIBLE); if (progressBar != null)
progressBar.setVisibility(android.view.View.VISIBLE);
query.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() { query.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
@Override @Override
public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) { public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) {
if (progressBar != null) progressBar.setVisibility(android.view.View.GONE); if (progressBar != null)
progressBar.setVisibility(android.view.View.GONE);
restaurantsList.clear(); restaurantsList.clear();
for (com.google.firebase.database.DataSnapshot ds : snapshot.getChildren()) { for (com.google.firebase.database.DataSnapshot ds : snapshot.getChildren()) {
String role = ds.child("role").getValue(String.class); String role = ds.child("role").getValue(String.class);
String accountType = ds.child("accountType").getValue(String.class); String accountType = ds.child("accountType").getValue(String.class);
if ("ADMIN".equalsIgnoreCase(role) || "ESTABELECIMENTO".equalsIgnoreCase(accountType)) { if ("ADMIN".equalsIgnoreCase(role) || "ESTABELECIMENTO".equalsIgnoreCase(accountType)) {
String name = ds.child("establishmentName").getValue(String.class); String name = ds.child("establishmentName").getValue(String.class);
if (name == null) name = ds.child("displayName").getValue(String.class); if (name == null)
name = ds.child("displayName").getValue(String.class);
String email = ds.child("email").getValue(String.class); String email = ds.child("email").getValue(String.class);
String cat = ds.child("category").getValue(String.class); String cat = ds.child("category").getValue(String.class);
String logoUrl = ds.child("logoUrl").getValue(String.class); String logoUrl = ds.child("logoUrl").getValue(String.class);
if (name != null && email != null) { if (name != null && email != null) {
restaurantsList.add(new com.example.pap_teste.models.Restaurant(name, cat, email, false, logoUrl)); restaurantsList
.add(new com.example.pap_teste.models.Restaurant(name, cat, email, false, logoUrl));
} }
} }
} }
RestaurantAdapter adapter = new RestaurantAdapter(restaurantsList, restaurant -> { RestaurantAdapter adapter = new RestaurantAdapter(restaurantsList, restaurant -> {
selectedRestaurant = restaurant; selectedRestaurant = restaurant;
currentState = State.DETAILS; currentState = State.DETAILS;
@@ -161,8 +170,10 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
@Override @Override
public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) { public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {
if (progressBar != null) progressBar.setVisibility(android.view.View.GONE); if (progressBar != null)
android.widget.Toast.makeText(ExplorarRestaurantesActivity.this, "Erro ao carregar restaurantes.", android.widget.Toast.LENGTH_SHORT).show(); progressBar.setVisibility(android.view.View.GONE);
android.widget.Toast.makeText(ExplorarRestaurantesActivity.this, "Erro ao carregar restaurantes.",
android.widget.Toast.LENGTH_SHORT).show();
} }
}); });
} }
@@ -178,7 +189,8 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
new android.app.DatePickerDialog(this, (view, year, month, dayOfMonth) -> { new android.app.DatePickerDialog(this, (view, year, month, dayOfMonth) -> {
selectedDate = dayOfMonth + "/" + (month + 1) + "/" + year; selectedDate = dayOfMonth + "/" + (month + 1) + "/" + year;
btnDate.setText(selectedDate); btnDate.setText(selectedDate);
}, cal.get(java.util.Calendar.YEAR), cal.get(java.util.Calendar.MONTH), cal.get(java.util.Calendar.DAY_OF_MONTH)).show(); }, cal.get(java.util.Calendar.YEAR), cal.get(java.util.Calendar.MONTH),
cal.get(java.util.Calendar.DAY_OF_MONTH)).show();
}); });
btnTime.setOnClickListener(v -> { btnTime.setOnClickListener(v -> {
@@ -201,9 +213,11 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
} }
private void uploadRestaurantPhoto(android.net.Uri imageUri) { private void uploadRestaurantPhoto(android.net.Uri imageUri) {
if (selectedRestaurant == null || selectedRestaurant.getEmail() == null) return; if (selectedRestaurant == null || selectedRestaurant.getEmail() == null)
return;
String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_"); String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_");
com.google.firebase.storage.StorageReference storageRef = com.google.firebase.storage.FirebaseStorage.getInstance().getReference() com.google.firebase.storage.StorageReference storageRef = com.google.firebase.storage.FirebaseStorage
.getInstance().getReference()
.child("restaurant_photos/" + encodedEmail + "/" + java.util.UUID.randomUUID().toString()); .child("restaurant_photos/" + encodedEmail + "/" + java.util.UUID.randomUUID().toString());
storageRef.putFile(imageUri).addOnSuccessListener(taskSnapshot -> { storageRef.putFile(imageUri).addOnSuccessListener(taskSnapshot -> {
@@ -212,17 +226,20 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("photos").child(encodedEmail) com.google.firebase.database.FirebaseDatabase.getInstance().getReference("photos").child(encodedEmail)
.push().child("url").setValue(photoUrl).addOnCompleteListener(task -> { .push().child("url").setValue(photoUrl).addOnCompleteListener(task -> {
if (task.isSuccessful()) { if (task.isSuccessful()) {
android.widget.Toast.makeText(this, "Foto adicionada com sucesso!", android.widget.Toast.LENGTH_SHORT).show(); android.widget.Toast.makeText(this, "Foto adicionada com sucesso!",
android.widget.Toast.LENGTH_SHORT).show();
} }
}); });
}); });
}).addOnFailureListener(e -> { }).addOnFailureListener(e -> {
android.widget.Toast.makeText(this, "Falha no upload: " + e.getMessage(), android.widget.Toast.LENGTH_LONG).show(); android.widget.Toast.makeText(this, "Falha no upload: " + e.getMessage(), android.widget.Toast.LENGTH_LONG)
.show();
}); });
} }
private void showReviewsDialog() { private void showReviewsDialog() {
if (selectedRestaurant == null || selectedRestaurant.getEmail() == null) return; if (selectedRestaurant == null || selectedRestaurant.getEmail() == null)
return;
String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_"); String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_");
android.view.View dialogView = getLayoutInflater().inflate(R.layout.dialog_reviews_list, null); android.view.View dialogView = getLayoutInflater().inflate(R.layout.dialog_reviews_list, null);
@@ -244,11 +261,13 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
addReviewDialog(); addReviewDialog();
}); });
com.google.firebase.database.DatabaseReference reviewsRef = com.google.firebase.database.FirebaseDatabase.getInstance() com.google.firebase.database.DatabaseReference reviewsRef = com.google.firebase.database.FirebaseDatabase
.getInstance()
.getReference("reviews").child(encodedEmail); .getReference("reviews").child(encodedEmail);
String currentUserEmail = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null ? String currentUserEmail = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null
com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser().getEmail() : null; ? com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser().getEmail()
: null;
reviewsRef.addValueEventListener(new com.google.firebase.database.ValueEventListener() { reviewsRef.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
@Override @Override
@@ -259,8 +278,9 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
String text = dst.child("text").getValue(String.class); String text = dst.child("text").getValue(String.class);
String uEmail = dst.child("userEmail").getValue(String.class); String uEmail = dst.child("userEmail").getValue(String.class);
Float rating = dst.child("rating").getValue(Float.class); Float rating = dst.child("rating").getValue(Float.class);
if (rating == null) rating = 0f; if (rating == null)
rating = 0f;
com.example.pap_teste.models.Review rev = new com.example.pap_teste.models.Review( com.example.pap_teste.models.Review rev = new com.example.pap_teste.models.Review(
dst.getKey(), author, text, rating, uEmail); dst.getKey(), author, text, rating, uEmail);
@@ -292,7 +312,8 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
@Override @Override
public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) { public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {
android.widget.Toast.makeText(ExplorarRestaurantesActivity.this, "Erro ao carregar avaliações.", android.widget.Toast.LENGTH_SHORT).show(); android.widget.Toast.makeText(ExplorarRestaurantesActivity.this, "Erro ao carregar avaliações.",
android.widget.Toast.LENGTH_SHORT).show();
} }
}); });
@@ -300,14 +321,17 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
} }
private void deleteReview(String reviewKey) { private void deleteReview(String reviewKey) {
if (selectedRestaurant == null || selectedRestaurant.getEmail() == null) return; if (selectedRestaurant == null || selectedRestaurant.getEmail() == null)
return;
String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_"); String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_");
com.google.firebase.database.DatabaseReference reviewsRef = com.google.firebase.database.FirebaseDatabase.getInstance() com.google.firebase.database.DatabaseReference reviewsRef = com.google.firebase.database.FirebaseDatabase
.getInstance()
.getReference("reviews").child(encodedEmail); .getReference("reviews").child(encodedEmail);
reviewsRef.child(reviewKey).removeValue().addOnSuccessListener(aVoid -> { reviewsRef.child(reviewKey).removeValue().addOnSuccessListener(aVoid -> {
com.google.android.material.snackbar.Snackbar.make(findViewById(R.id.explorarRoot), "Avaliação removida", com.google.android.material.snackbar.Snackbar.LENGTH_SHORT).show(); com.google.android.material.snackbar.Snackbar.make(findViewById(R.id.explorarRoot), "Avaliação removida",
com.google.android.material.snackbar.Snackbar.LENGTH_SHORT).show();
recalculateRestaurantAverage(encodedEmail); recalculateRestaurantAverage(encodedEmail);
}); });
} }
@@ -316,7 +340,8 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reviews").child(encodedEmail) com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reviews").child(encodedEmail)
.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() { .addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
@Override @Override
public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) { public void onDataChange(
@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) {
double totalRating = 0; double totalRating = 0;
int count = 0; int count = 0;
for (com.google.firebase.database.DataSnapshot dst : snapshot.getChildren()) { for (com.google.firebase.database.DataSnapshot dst : snapshot.getChildren()) {
@@ -326,27 +351,31 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
count++; count++;
} }
} }
double newAvg = count > 0 ? (totalRating / count) : 0.0; double newAvg = count > 0 ? (totalRating / count) : 0.0;
java.util.Map<String, Object> updates = new java.util.HashMap<>(); java.util.Map<String, Object> updates = new java.util.HashMap<>();
updates.put("ratingAvg", newAvg); updates.put("ratingAvg", newAvg);
updates.put("ratingCount", count); updates.put("ratingCount", count);
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("users") com.google.firebase.database.FirebaseDatabase.getInstance().getReference("Restaurantes")
.child(encodedEmail).updateChildren(updates); .child(encodedEmail).updateChildren(updates);
} }
@Override @Override
public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {} public void onCancelled(
@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {
}
}); });
} }
private void addReviewDialog() { private void addReviewDialog() {
if (selectedRestaurant == null || selectedRestaurant.getEmail() == null) return; if (selectedRestaurant == null || selectedRestaurant.getEmail() == null)
return;
android.view.View dialogView = getLayoutInflater().inflate(R.layout.dialog_leave_review, null); android.view.View dialogView = getLayoutInflater().inflate(R.layout.dialog_leave_review, null);
com.example.pap_teste.components.InteractiveRatingBar ratingBar = dialogView.findViewById(R.id.interactiveRatingBar); com.example.pap_teste.components.InteractiveRatingBar ratingBar = dialogView
.findViewById(R.id.interactiveRatingBar);
android.widget.EditText input = dialogView.findViewById(R.id.etReviewComment); android.widget.EditText input = dialogView.findViewById(R.id.etReviewComment);
android.widget.Button btnSubmit = dialogView.findViewById(R.id.btnSubmitReview); android.widget.Button btnSubmit = dialogView.findViewById(R.id.btnSubmitReview);
android.widget.Button btnCancel = dialogView.findViewById(R.id.btnCancelReview); android.widget.Button btnCancel = dialogView.findViewById(R.id.btnCancelReview);
@@ -356,7 +385,8 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
input.addTextChangedListener(new android.text.TextWatcher() { input.addTextChangedListener(new android.text.TextWatcher() {
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override @Override
public void onTextChanged(CharSequence s, int start, int before, int count) { public void onTextChanged(CharSequence s, int start, int before, int count) {
@@ -366,33 +396,37 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
} }
@Override @Override
public void afterTextChanged(android.text.Editable s) {} public void afterTextChanged(android.text.Editable s) {
}
}); });
androidx.appcompat.app.AlertDialog dialog = new androidx.appcompat.app.AlertDialog.Builder(this) androidx.appcompat.app.AlertDialog dialog = new androidx.appcompat.app.AlertDialog.Builder(this)
.setView(dialogView) .setView(dialogView)
.create(); .create();
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
btnCancel.setOnClickListener(v -> dialog.dismiss()); btnCancel.setOnClickListener(v -> dialog.dismiss());
btnSubmit.setOnClickListener(v -> { btnSubmit.setOnClickListener(v -> {
float rating = (float) ratingBar.getRating(); float rating = (float) ratingBar.getRating();
String revText = input.getText().toString().trim(); String revText = input.getText().toString().trim();
com.google.firebase.auth.FirebaseUser currentUser = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser(); com.google.firebase.auth.FirebaseUser currentUser = com.google.firebase.auth.FirebaseAuth.getInstance()
.getCurrentUser();
if (currentUser != null && currentUser.getEmail() != null) { if (currentUser != null && currentUser.getEmail() != null) {
String userDoc = currentUser.getEmail().replace(".", "_").replace("@", "_at_"); String userDoc = currentUser.getEmail().replace(".", "_").replace("@", "_at_");
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("users").child(userDoc).get().addOnSuccessListener(snapshot -> { com.google.firebase.database.FirebaseDatabase.getInstance().getReference("Clientes").child(userDoc).get()
String authorName = snapshot.exists() && snapshot.child("displayName").getValue(String.class) != null .addOnSuccessListener(snapshot -> {
? snapshot.child("displayName").getValue(String.class) String authorName = snapshot.exists()
: "Visitante"; && snapshot.child("displayName").getValue(String.class) != null
submitReviewToFirebase(authorName, revText, rating); ? snapshot.child("displayName").getValue(String.class)
dialog.dismiss(); : "Visitante";
}).addOnFailureListener(e -> { submitReviewToFirebase(authorName, revText, rating);
submitReviewToFirebase("Visitante", revText, rating); dialog.dismiss();
dialog.dismiss(); }).addOnFailureListener(e -> {
}); submitReviewToFirebase("Visitante", revText, rating);
dialog.dismiss();
});
} else { } else {
submitReviewToFirebase("Visitante", revText, rating); submitReviewToFirebase("Visitante", revText, rating);
dialog.dismiss(); dialog.dismiss();
@@ -404,10 +438,11 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
private void submitReviewToFirebase(String authorName, String revText, float newRating) { private void submitReviewToFirebase(String authorName, String revText, float newRating) {
String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_"); String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_");
com.google.firebase.auth.FirebaseUser currentUser = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser(); com.google.firebase.auth.FirebaseUser currentUser = com.google.firebase.auth.FirebaseAuth.getInstance()
.getCurrentUser();
String uEmail = currentUser != null ? currentUser.getEmail() : null; String uEmail = currentUser != null ? currentUser.getEmail() : null;
// 1. Guardar a Review // 1. Guardar a Review
java.util.Map<String, Object> review = new java.util.HashMap<>(); java.util.Map<String, Object> review = new java.util.HashMap<>();
review.put("author", authorName); review.put("author", authorName);
@@ -419,32 +454,39 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reviews") com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reviews")
.child(encodedEmail).push().setValue(review).addOnCompleteListener(task -> { .child(encodedEmail).push().setValue(review).addOnCompleteListener(task -> {
if (task.isSuccessful()) { if (task.isSuccessful()) {
com.google.android.material.snackbar.Snackbar.make(findViewById(R.id.explorarRoot), "Obrigado pela tua avaliação!", com.google.android.material.snackbar.Snackbar.LENGTH_LONG).show(); com.google.android.material.snackbar.Snackbar
.make(findViewById(R.id.explorarRoot), "Obrigado pela tua avaliação!",
com.google.android.material.snackbar.Snackbar.LENGTH_LONG)
.show();
} }
}); });
// 2. Atualizar Média no Restaurante // 2. Atualizar Média no Restaurante
com.google.firebase.database.DatabaseReference restRef = com.google.firebase.database.FirebaseDatabase.getInstance().getReference("users").child(encodedEmail); com.google.firebase.database.DatabaseReference restRef = com.google.firebase.database.FirebaseDatabase
.getInstance().getReference("Restaurantes").child(encodedEmail);
restRef.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() { restRef.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
@Override @Override
public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) { public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) {
Double currentAvg = snapshot.child("ratingAvg").getValue(Double.class); Double currentAvg = snapshot.child("ratingAvg").getValue(Double.class);
Integer currentCount = snapshot.child("ratingCount").getValue(Integer.class); Integer currentCount = snapshot.child("ratingCount").getValue(Integer.class);
if (currentAvg == null) currentAvg = 0.0; if (currentAvg == null)
if (currentCount == null) currentCount = 0; currentAvg = 0.0;
if (currentCount == null)
currentCount = 0;
double newAvg = ((currentAvg * currentCount) + newRating) / (currentCount + 1); double newAvg = ((currentAvg * currentCount) + newRating) / (currentCount + 1);
java.util.Map<String, Object> updates = new java.util.HashMap<>(); java.util.Map<String, Object> updates = new java.util.HashMap<>();
updates.put("ratingAvg", newAvg); updates.put("ratingAvg", newAvg);
updates.put("ratingCount", currentCount + 1); updates.put("ratingCount", currentCount + 1);
restRef.updateChildren(updates); restRef.updateChildren(updates);
} }
@Override @Override
public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {} public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {
}
}); });
} }
@@ -453,7 +495,8 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
int partySize = 0; int partySize = 0;
try { try {
partySize = Integer.parseInt(etPartySize.getText().toString()); partySize = Integer.parseInt(etPartySize.getText().toString());
} catch (Exception e) {} } catch (Exception e) {
}
if (selectedDate == null || selectedTime == null || partySize == 0) { if (selectedDate == null || selectedTime == null || partySize == 0) {
android.widget.Toast.makeText(this, "Por favor, selecione data, hora e número de pessoas.", android.widget.Toast.makeText(this, "Por favor, selecione data, hora e número de pessoas.",

View File

@@ -51,7 +51,7 @@ public class FavoritosActivity extends AppCompatActivity {
rv = findViewById(R.id.rvFavoritos); rv = findViewById(R.id.rvFavoritos);
progressBar = findViewById(R.id.progressBar); progressBar = findViewById(R.id.progressBar);
emptyState = findViewById(R.id.emptyState); emptyState = findViewById(R.id.emptyState);
list = new ArrayList<>(); list = new ArrayList<>();
adapter = new RestaurantAdapter(list, restaurant -> { adapter = new RestaurantAdapter(list, restaurant -> {
android.content.Intent intent = new android.content.Intent(this, ExplorarRestaurantesActivity.class); android.content.Intent intent = new android.content.Intent(this, ExplorarRestaurantesActivity.class);
@@ -67,13 +67,14 @@ public class FavoritosActivity extends AppCompatActivity {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null && user.getEmail() != null) { if (user != null && user.getEmail() != null) {
String encodedUserEmail = user.getEmail().replace(".", "_").replace("@", "_at_"); String encodedUserEmail = user.getEmail().replace(".", "_").replace("@", "_at_");
DatabaseReference favRef = FirebaseDatabase.getInstance().getReference("users") DatabaseReference favRef = FirebaseDatabase.getInstance().getReference("Clientes")
.child(encodedUserEmail).child("favorites"); .child(encodedUserEmail).child("favorites");
favRef.addValueEventListener(new ValueEventListener() { favRef.addValueEventListener(new ValueEventListener() {
@Override @Override
public void onDataChange(@NonNull DataSnapshot snapshot) { public void onDataChange(@NonNull DataSnapshot snapshot) {
if (progressBar != null) progressBar.setVisibility(android.view.View.GONE); if (progressBar != null)
progressBar.setVisibility(android.view.View.GONE);
list.clear(); list.clear();
for (DataSnapshot ds : snapshot.getChildren()) { for (DataSnapshot ds : snapshot.getChildren()) {
Restaurant restaurant = ds.getValue(Restaurant.class); Restaurant restaurant = ds.getValue(Restaurant.class);
@@ -82,7 +83,7 @@ public class FavoritosActivity extends AppCompatActivity {
} }
} }
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
if (emptyState != null) { if (emptyState != null) {
emptyState.setVisibility(list.isEmpty() ? android.view.View.VISIBLE : android.view.View.GONE); emptyState.setVisibility(list.isEmpty() ? android.view.View.VISIBLE : android.view.View.GONE);
} }
@@ -90,7 +91,8 @@ public class FavoritosActivity extends AppCompatActivity {
@Override @Override
public void onCancelled(@NonNull DatabaseError error) { public void onCancelled(@NonNull DatabaseError error) {
if (progressBar != null) progressBar.setVisibility(android.view.View.GONE); if (progressBar != null)
progressBar.setVisibility(android.view.View.GONE);
Toast.makeText(FavoritosActivity.this, "Erro ao carregar favoritos.", Toast.LENGTH_SHORT).show(); Toast.makeText(FavoritosActivity.this, "Erro ao carregar favoritos.", Toast.LENGTH_SHORT).show();
} }
}); });

View File

@@ -24,7 +24,8 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
private List<Restaurant> restaurants; private List<Restaurant> restaurants;
private RestaurantAdapter.OnRestaurantClickListener listener; private RestaurantAdapter.OnRestaurantClickListener listener;
public FeaturedRestaurantAdapter(List<Restaurant> restaurants, RestaurantAdapter.OnRestaurantClickListener listener) { public FeaturedRestaurantAdapter(List<Restaurant> restaurants,
RestaurantAdapter.OnRestaurantClickListener listener) {
this.restaurants = restaurants; this.restaurants = restaurants;
this.listener = listener; this.listener = listener;
} }
@@ -41,15 +42,16 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
Restaurant restaurant = restaurants.get(position); Restaurant restaurant = restaurants.get(position);
holder.txtName.setText(restaurant.getName()); holder.txtName.setText(restaurant.getName());
holder.txtCategory.setText("" + restaurant.getCategory()); holder.txtCategory.setText("" + restaurant.getCategory());
if (holder.txtRating != null) { if (holder.txtRating != null) {
if (restaurant.getRatingAvg() != null && restaurant.getRatingAvg() > 0) { if (restaurant.getRatingAvg() != null && restaurant.getRatingAvg() > 0) {
holder.txtRating.setText(String.format(java.util.Locale.getDefault(), "%.1f", restaurant.getRatingAvg())); holder.txtRating
.setText(String.format(java.util.Locale.getDefault(), "%.1f", restaurant.getRatingAvg()));
} else { } else {
holder.txtRating.setText("Novo"); holder.txtRating.setText("Novo");
} }
} }
if (restaurant.getLogoUrl() != null && !restaurant.getLogoUrl().isEmpty()) { if (restaurant.getLogoUrl() != null && !restaurant.getLogoUrl().isEmpty()) {
com.bumptech.glide.Glide.with(holder.itemView.getContext()) com.bumptech.glide.Glide.with(holder.itemView.getContext())
.load(restaurant.getLogoUrl()) .load(restaurant.getLogoUrl())
@@ -58,7 +60,7 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
} else { } else {
holder.imgCover.setImageResource(R.mipmap.ic_launcher); holder.imgCover.setImageResource(R.mipmap.ic_launcher);
} }
holder.itemView.setOnClickListener(v -> { holder.itemView.setOnClickListener(v -> {
if (listener != null) { if (listener != null) {
listener.onRestaurantClick(restaurant); listener.onRestaurantClick(restaurant);
@@ -70,7 +72,7 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
if (user != null && user.getEmail() != null && restaurant.getEmail() != null) { if (user != null && user.getEmail() != null && restaurant.getEmail() != null) {
String encodedUserEmail = user.getEmail().replace(".", "_").replace("@", "_at_"); String encodedUserEmail = user.getEmail().replace(".", "_").replace("@", "_at_");
String encodedRestEmail = restaurant.getEmail().replace(".", "_").replace("@", "_at_"); String encodedRestEmail = restaurant.getEmail().replace(".", "_").replace("@", "_at_");
DatabaseReference favRef = FirebaseDatabase.getInstance().getReference("users") DatabaseReference favRef = FirebaseDatabase.getInstance().getReference("Clientes")
.child(encodedUserEmail).child("favorites").child(encodedRestEmail); .child(encodedUserEmail).child("favorites").child(encodedRestEmail);
// Read initial state // Read initial state
@@ -80,7 +82,8 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
holder.btnFavorite.setTag(snapshot.exists()); holder.btnFavorite.setTag(snapshot.exists());
if (snapshot.exists()) { if (snapshot.exists()) {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_on); holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_on);
holder.btnFavorite.setColorFilter(androidx.core.content.ContextCompat.getColor(holder.itemView.getContext(), R.color.colorPrimary)); holder.btnFavorite.setColorFilter(androidx.core.content.ContextCompat
.getColor(holder.itemView.getContext(), R.color.colorPrimary));
} else { } else {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off); holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off);
holder.btnFavorite.clearColorFilter(); holder.btnFavorite.clearColorFilter();
@@ -88,7 +91,8 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
} }
@Override @Override
public void onCancelled(@NonNull DatabaseError error) { } public void onCancelled(@NonNull DatabaseError error) {
}
}); });
holder.btnFavorite.setOnClickListener(v -> { holder.btnFavorite.setOnClickListener(v -> {
@@ -96,17 +100,20 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
boolean isFav = holder.btnFavorite.getTag() != null && (Boolean) holder.btnFavorite.getTag(); boolean isFav = holder.btnFavorite.getTag() != null && (Boolean) holder.btnFavorite.getTag();
boolean newFavState = !isFav; boolean newFavState = !isFav;
holder.btnFavorite.setTag(newFavState); holder.btnFavorite.setTag(newFavState);
if (newFavState) { if (newFavState) {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_on); holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_on);
holder.btnFavorite.setColorFilter(androidx.core.content.ContextCompat.getColor(holder.itemView.getContext(), R.color.colorPrimary)); holder.btnFavorite.setColorFilter(androidx.core.content.ContextCompat
.getColor(holder.itemView.getContext(), R.color.colorPrimary));
favRef.setValue(restaurant); favRef.setValue(restaurant);
com.google.android.material.snackbar.Snackbar.make(v, "Adicionado aos Favoritos!", com.google.android.material.snackbar.Snackbar.LENGTH_SHORT).show(); com.google.android.material.snackbar.Snackbar.make(v, "Adicionado aos Favoritos!",
com.google.android.material.snackbar.Snackbar.LENGTH_SHORT).show();
} else { } else {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off); holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off);
holder.btnFavorite.clearColorFilter(); holder.btnFavorite.clearColorFilter();
favRef.removeValue(); favRef.removeValue();
com.google.android.material.snackbar.Snackbar.make(v, "Removido dos Favoritos.", com.google.android.material.snackbar.Snackbar.LENGTH_SHORT).show(); com.google.android.material.snackbar.Snackbar.make(v, "Removido dos Favoritos.",
com.google.android.material.snackbar.Snackbar.LENGTH_SHORT).show();
} }
}); });
} }
@@ -122,6 +129,7 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
TextView txtName, txtCategory, txtRating; TextView txtName, txtCategory, txtRating;
ImageView imgCover; ImageView imgCover;
android.widget.ImageButton btnFavorite; android.widget.ImageButton btnFavorite;
public ViewHolder(@NonNull View itemView) { public ViewHolder(@NonNull View itemView) {
super(itemView); super(itemView);
txtName = itemView.findViewById(R.id.txtFeaturedName); txtName = itemView.findViewById(R.id.txtFeaturedName);

View File

@@ -49,11 +49,10 @@ public class ListaEsperaActivity extends AppCompatActivity {
restaurantEmail = getIntent().getStringExtra(MainActivity.EXTRA_EMAIL); restaurantEmail = getIntent().getStringExtra(MainActivity.EXTRA_EMAIL);
if (restaurantEmail == null) { if (restaurantEmail == null) {
// Se o extra não chegou, falha segura
if (com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null) { if (com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null) {
restaurantEmail = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser().getEmail(); restaurantEmail = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser().getEmail();
} else { } else {
restaurantEmail = "sabor_arte@restaurante.com"; restaurantEmail = ""; // Avoid hardcoded sabor_arte so we don't accidentally load wrong data
} }
} }

View File

@@ -110,29 +110,55 @@ public class MainActivity extends AppCompatActivity {
setupActionToggle(); setupActionToggle();
setupPrimaryAction(); setupPrimaryAction();
checkPermissions(); checkPermissions();
migrateUsersNodeToSeparateCollections();
}
private void migrateUsersNodeToSeparateCollections() {
if (databaseReference == null) return;
databaseReference.child("users").get().addOnCompleteListener(task -> {
if (task.isSuccessful() && task.getResult() != null && task.getResult().exists()) {
for (DataSnapshot userSnapshot : task.getResult().getChildren()) {
String accountType = userSnapshot.child("accountType").getValue(String.class);
String role = userSnapshot.child("role").getValue(String.class);
String targetCollection = "Clientes";
if ("ESTABELECIMENTO".equalsIgnoreCase(accountType) || "ADMIN".equalsIgnoreCase(role)) {
targetCollection = "Restaurantes";
}
databaseReference.child(targetCollection).child(userSnapshot.getKey())
.setValue(userSnapshot.getValue());
}
}
});
} }
private void checkPermissions() { private void checkPermissions() {
List<String> permissionsNeeded = new ArrayList<>(); List<String> permissionsNeeded = new ArrayList<>();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION); permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this,
Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_SCAN); permissionsNeeded.add(Manifest.permission.BLUETOOTH_SCAN);
} }
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this,
Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_CONNECT); permissionsNeeded.add(Manifest.permission.BLUETOOTH_CONNECT);
} }
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.READ_MEDIA_IMAGES); permissionsNeeded.add(Manifest.permission.READ_MEDIA_IMAGES);
} }
} else { } else {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE); permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
} }
} }
@@ -140,7 +166,8 @@ public class MainActivity extends AppCompatActivity {
if (!permissionsNeeded.isEmpty()) { if (!permissionsNeeded.isEmpty()) {
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setTitle("Permissões Necessárias") .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.") .setMessage(
"Para o correto funcionamento do check-in, serviços de proximidade e fotos da galeria, precisamos de algumas permissões.")
.setPositiveButton("Configurar", (dialog, which) -> { .setPositiveButton("Configurar", (dialog, which) -> {
permissionRequest.launch(permissionsNeeded.toArray(new String[0])); permissionRequest.launch(permissionsNeeded.toArray(new String[0]));
}) })
@@ -164,47 +191,52 @@ public class MainActivity extends AppCompatActivity {
inputEstablishmentPhone = findViewById(R.id.inputEstablishmentPhone); inputEstablishmentPhone = findViewById(R.id.inputEstablishmentPhone);
txtForgotPassword = findViewById(R.id.txtForgotPassword); txtForgotPassword = findViewById(R.id.txtForgotPassword);
iconPasswordVisibility = findViewById(R.id.iconPasswordVisibility); iconPasswordVisibility = findViewById(R.id.iconPasswordVisibility);
setupPasswordFeatures(); setupPasswordFeatures();
} }
private void setupPasswordFeatures() { private void setupPasswordFeatures() {
iconPasswordVisibility.setOnClickListener(v -> { iconPasswordVisibility.setOnClickListener(v -> {
isPasswordVisible = !isPasswordVisible; isPasswordVisible = !isPasswordVisible;
if (isPasswordVisible) { if (isPasswordVisible) {
inputPassword.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD); inputPassword.setInputType(android.text.InputType.TYPE_CLASS_TEXT
| android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
iconPasswordVisibility.setImageResource(R.drawable.ic_visibility); iconPasswordVisibility.setImageResource(R.drawable.ic_visibility);
} else { } else {
inputPassword.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD); inputPassword.setInputType(
android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD);
iconPasswordVisibility.setImageResource(R.drawable.ic_visibility_off); iconPasswordVisibility.setImageResource(R.drawable.ic_visibility_off);
} }
inputPassword.setSelection(inputPassword.getText().length()); inputPassword.setSelection(inputPassword.getText().length());
}); });
txtForgotPassword.setOnClickListener(v -> { txtForgotPassword.setOnClickListener(v -> {
String email = inputEmail.getText().toString().trim(); String email = inputEmail.getText().toString().trim();
if (TextUtils.isEmpty(email)) { if (TextUtils.isEmpty(email)) {
Toast.makeText(this, "Por favor, introduza o seu email primeiro.", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "Por favor, introduza o seu email primeiro.", Toast.LENGTH_SHORT).show();
return; return;
} }
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setTitle("Recuperar palavra-passe") .setTitle("Recuperar palavra-passe")
.setMessage("Deseja enviar um email de recuperação para " + email + "?") .setMessage("Deseja enviar um email de recuperação para " + email + "?")
.setPositiveButton("Sim", (dialog, which) -> { .setPositiveButton("Sim", (dialog, which) -> {
if (firebaseAuth != null) { if (firebaseAuth != null) {
firebaseAuth.sendPasswordResetEmail(email) firebaseAuth.sendPasswordResetEmail(email)
.addOnCompleteListener(task -> { .addOnCompleteListener(task -> {
if (task.isSuccessful()) { if (task.isSuccessful()) {
Toast.makeText(MainActivity.this, "Email de recuperação enviado!", Toast.LENGTH_LONG).show(); Toast.makeText(MainActivity.this, "Email de recuperação enviado!",
} else { Toast.LENGTH_LONG).show();
Toast.makeText(MainActivity.this, "Falha ao enviar email. Verifique se o endereço está correto.", Toast.LENGTH_LONG).show(); } else {
} Toast.makeText(MainActivity.this,
}); "Falha ao enviar email. Verifique se o endereço está correto.",
} Toast.LENGTH_LONG).show();
}) }
.setNegativeButton("Não", null) });
.show(); }
})
.setNegativeButton("Não", null)
.show();
}); });
} }
@@ -274,7 +306,7 @@ public class MainActivity extends AppCompatActivity {
inputEstablishmentName.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE); inputEstablishmentName.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE);
inputEstablishmentEmail.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE); inputEstablishmentEmail.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE);
inputEstablishmentPhone.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE); inputEstablishmentPhone.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE);
if (txtForgotPassword != null) { if (txtForgotPassword != null) {
txtForgotPassword.setVisibility(creatingAccount ? View.GONE : View.VISIBLE); txtForgotPassword.setVisibility(creatingAccount ? View.GONE : View.VISIBLE);
} }
@@ -439,33 +471,35 @@ public class MainActivity extends AppCompatActivity {
private void fetchAccountAndNavigate(String email, String fallbackName, String resolvedRole) { private void fetchAccountAndNavigate(String email, String fallbackName, String resolvedRole) {
if (databaseReference == null) { if (databaseReference == null) {
Toast.makeText(this, "Firebase indisponível.", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "Firebase indisponível.", Toast.LENGTH_SHORT).show();
navigateToDashboard(email, fallbackName, resolvedRole); if (firebaseAuth != null) firebaseAuth.signOut();
return; return;
} }
String documentId = buildDocumentId(email); String documentId = buildDocumentId(email);
databaseReference.child("users").child(documentId).get().addOnCompleteListener(task -> { String collectionPath = selectedAccountType == AccountType.ESTABELECIMENTO ? "Restaurantes" : "Clientes";
databaseReference.child(collectionPath).child(documentId).get().addOnCompleteListener(task -> {
if (!task.isSuccessful()) { if (!task.isSuccessful()) {
android.util.Log.e("LoginError", "Database check failed", task.getException()); android.util.Log.e("LoginError", "Database check failed", task.getException());
Toast.makeText(this, "Falha ao validar perfil na cloud. A entrar em modo básico.", Toast.LENGTH_SHORT) Toast.makeText(this, "Falha ao validar perfil. Tente novamente.", Toast.LENGTH_SHORT)
.show(); .show();
navigateToDashboard(email, fallbackName, resolvedRole); if (firebaseAuth != null) firebaseAuth.signOut();
return; return;
} }
DataSnapshot snapshot = task.getResult(); DataSnapshot snapshot = task.getResult();
if (snapshot == null || !snapshot.exists()) { if (snapshot == null || !snapshot.exists()) {
// Toast.makeText(this, "Conta sem perfil na cloud. A entrar em modo básico.", String tipo = selectedAccountType == AccountType.ESTABELECIMENTO ? "Estabelecimento" : "Cliente";
// Toast.LENGTH_SHORT).show(); Toast.makeText(this, "Conta não encontrada como " + tipo + ".\nPor favor, crie uma conta nova.", Toast.LENGTH_LONG).show();
navigateToDashboard(email, fallbackName, resolvedRole); if (firebaseAuth != null) firebaseAuth.signOut();
return; return;
} }
String accountTypeInFirebase = snapshot.child("accountType").getValue(String.class); String accountTypeInFirebase = snapshot.child("accountType").getValue(String.class);
if (accountTypeInFirebase != null if (accountTypeInFirebase != null
&& !accountTypeInFirebase.equalsIgnoreCase(selectedAccountType.name())) { && !accountTypeInFirebase.equalsIgnoreCase(selectedAccountType.name())) {
Toast.makeText(this, "Tipo de conta não corresponde ao registo no Firebase.", Toast.LENGTH_SHORT) Toast.makeText(this, "Tipo de conta não corresponde ao registo.\nPor favor verifique se escolheu a opção correta.", Toast.LENGTH_LONG)
.show(); .show();
if (firebaseAuth != null) firebaseAuth.signOut();
return; return;
} }
@@ -533,7 +567,8 @@ public class MainActivity extends AppCompatActivity {
payload.put("establishmentPhone", establishmentPhone); payload.put("establishmentPhone", establishmentPhone);
} }
databaseReference.child("users").child(documentId).updateChildren(payload) String collectionPath = selectedAccountType == AccountType.ESTABELECIMENTO ? "Restaurantes" : "Clientes";
databaseReference.child(collectionPath).child(documentId).updateChildren(payload)
.addOnSuccessListener(unused -> { .addOnSuccessListener(unused -> {
Toast.makeText(this, "Conta guardada na cloud.", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "Conta guardada na cloud.", Toast.LENGTH_SHORT).show();
if (onSuccess != null) { if (onSuccess != null) {

View File

@@ -102,7 +102,7 @@ public class NovaReservaActivity extends AppCompatActivity {
private void setupRestaurants() { private void setupRestaurants() {
java.util.List<com.example.pap_teste.models.Restaurant> filteredList = new java.util.ArrayList<>(); java.util.List<com.example.pap_teste.models.Restaurant> filteredList = new java.util.ArrayList<>();
com.google.firebase.database.DatabaseReference usersRef = com.google.firebase.database.FirebaseDatabase com.google.firebase.database.DatabaseReference usersRef = com.google.firebase.database.FirebaseDatabase
.getInstance().getReference("users"); .getInstance().getReference("Restaurantes");
if (progressBar != null) if (progressBar != null)
progressBar.setVisibility(android.view.View.VISIBLE); progressBar.setVisibility(android.view.View.VISIBLE);

View File

@@ -53,7 +53,7 @@ public class ProfileDashboardActivity extends AppCompatActivity {
documentId = email.replace(".", "_").replace("@", "_at_"); documentId = email.replace(".", "_").replace("@", "_at_");
} }
databaseReference = FirebaseDatabase.getInstance().getReference().child("users"); databaseReference = FirebaseDatabase.getInstance().getReference().child("Clientes");
inputName = findViewById(R.id.inputProfileName); inputName = findViewById(R.id.inputProfileName);
inputPhone = findViewById(R.id.inputProfilePhone); inputPhone = findViewById(R.id.inputProfilePhone);

View File

@@ -45,16 +45,18 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
public void onBindViewHolder(@NonNull ViewHolder holder, int position) { public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Restaurant restaurant = restaurants.get(position); Restaurant restaurant = restaurants.get(position);
holder.text1.setText(restaurant.getName()); holder.text1.setText(restaurant.getName());
holder.text2.setText(restaurant.getCategory() + (restaurant.isAvailable() ? " - Disponível" : " - Indisponível")); holder.text2
.setText(restaurant.getCategory() + (restaurant.isAvailable() ? " - Disponível" : " - Indisponível"));
if (holder.txtRating != null) { if (holder.txtRating != null) {
if (restaurant.getRatingAvg() != null && restaurant.getRatingAvg() > 0) { if (restaurant.getRatingAvg() != null && restaurant.getRatingAvg() > 0) {
holder.txtRating.setText(String.format(java.util.Locale.getDefault(), "%.1f", restaurant.getRatingAvg())); holder.txtRating
.setText(String.format(java.util.Locale.getDefault(), "%.1f", restaurant.getRatingAvg()));
} else { } else {
holder.txtRating.setText("Novo"); holder.txtRating.setText("Novo");
} }
} }
if (restaurant.getLogoUrl() != null && !restaurant.getLogoUrl().isEmpty()) { if (restaurant.getLogoUrl() != null && !restaurant.getLogoUrl().isEmpty()) {
com.bumptech.glide.Glide.with(holder.itemView.getContext()) com.bumptech.glide.Glide.with(holder.itemView.getContext())
.load(restaurant.getLogoUrl()) .load(restaurant.getLogoUrl())
@@ -63,7 +65,7 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
} else { } else {
holder.imgThumb.setImageResource(R.mipmap.ic_launcher); holder.imgThumb.setImageResource(R.mipmap.ic_launcher);
} }
holder.itemView.setOnClickListener(v -> { holder.itemView.setOnClickListener(v -> {
if (listener != null) { if (listener != null) {
listener.onRestaurantClick(restaurant); listener.onRestaurantClick(restaurant);
@@ -82,7 +84,7 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
if (user != null && user.getEmail() != null && restaurant.getEmail() != null) { if (user != null && user.getEmail() != null && restaurant.getEmail() != null) {
String encodedUserEmail = user.getEmail().replace(".", "_").replace("@", "_at_"); String encodedUserEmail = user.getEmail().replace(".", "_").replace("@", "_at_");
String encodedRestEmail = restaurant.getEmail().replace(".", "_").replace("@", "_at_"); String encodedRestEmail = restaurant.getEmail().replace(".", "_").replace("@", "_at_");
DatabaseReference favRef = FirebaseDatabase.getInstance().getReference("users") DatabaseReference favRef = FirebaseDatabase.getInstance().getReference("Clientes")
.child(encodedUserEmail).child("favorites").child(encodedRestEmail); .child(encodedUserEmail).child("favorites").child(encodedRestEmail);
// Read initial state // Read initial state
@@ -92,7 +94,8 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
holder.btnFavorite.setTag(snapshot.exists()); holder.btnFavorite.setTag(snapshot.exists());
if (snapshot.exists()) { if (snapshot.exists()) {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_on); holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_on);
holder.btnFavorite.setColorFilter(androidx.core.content.ContextCompat.getColor(holder.itemView.getContext(), R.color.colorPrimary)); holder.btnFavorite.setColorFilter(androidx.core.content.ContextCompat
.getColor(holder.itemView.getContext(), R.color.colorPrimary));
} else { } else {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off); holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off);
holder.btnFavorite.clearColorFilter(); holder.btnFavorite.clearColorFilter();
@@ -100,7 +103,8 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
} }
@Override @Override
public void onCancelled(@NonNull DatabaseError error) { } public void onCancelled(@NonNull DatabaseError error) {
}
}); });
holder.btnFavorite.setOnClickListener(v -> { holder.btnFavorite.setOnClickListener(v -> {
@@ -108,17 +112,20 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
boolean isFav = holder.btnFavorite.getTag() != null && (Boolean) holder.btnFavorite.getTag(); boolean isFav = holder.btnFavorite.getTag() != null && (Boolean) holder.btnFavorite.getTag();
boolean newFavState = !isFav; boolean newFavState = !isFav;
holder.btnFavorite.setTag(newFavState); holder.btnFavorite.setTag(newFavState);
if (newFavState) { if (newFavState) {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_on); holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_on);
holder.btnFavorite.setColorFilter(androidx.core.content.ContextCompat.getColor(holder.itemView.getContext(), R.color.colorPrimary)); holder.btnFavorite.setColorFilter(androidx.core.content.ContextCompat
.getColor(holder.itemView.getContext(), R.color.colorPrimary));
favRef.setValue(restaurant); favRef.setValue(restaurant);
com.google.android.material.snackbar.Snackbar.make(v, "Adicionado aos Favoritos!", com.google.android.material.snackbar.Snackbar.LENGTH_SHORT).show(); com.google.android.material.snackbar.Snackbar.make(v, "Adicionado aos Favoritos!",
com.google.android.material.snackbar.Snackbar.LENGTH_SHORT).show();
} else { } else {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off); holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off);
holder.btnFavorite.clearColorFilter(); holder.btnFavorite.clearColorFilter();
favRef.removeValue(); favRef.removeValue();
com.google.android.material.snackbar.Snackbar.make(v, "Removido dos Favoritos.", com.google.android.material.snackbar.Snackbar.LENGTH_SHORT).show(); com.google.android.material.snackbar.Snackbar.make(v, "Removido dos Favoritos.",
com.google.android.material.snackbar.Snackbar.LENGTH_SHORT).show();
} }
}); });
} }
@@ -134,6 +141,7 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
ImageButton btnFavorite; ImageButton btnFavorite;
android.widget.ImageView imgThumb; android.widget.ImageView imgThumb;
Button btnReservar; Button btnReservar;
public ViewHolder(@NonNull View itemView) { public ViewHolder(@NonNull View itemView) {
super(itemView); super(itemView);
text1 = itemView.findViewById(R.id.txtRestaurantName); text1 = itemView.findViewById(R.id.txtRestaurantName);