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() {
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) {
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;
}
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() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
@@ -161,7 +163,8 @@ public class CheckInAntecipadoActivity extends AppCompatActivity implements Loca
}
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;
}
try {

View File

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

View File

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

View File

@@ -42,8 +42,13 @@ public class DetalhesReservasActivity extends AppCompatActivity {
});
restaurantEmail = getIntent().getStringExtra(MainActivity.EXTRA_EMAIL);
if (restaurantEmail == null)
restaurantEmail = "sabor_arte@restaurante.com";
if (restaurantEmail == null) {
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();
setupList();

View File

@@ -46,27 +46,49 @@ public class EstablishmentDashboardActivity extends AppCompatActivity {
Button btnSettings = findViewById(R.id.btnDefinicoes);
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 -> {
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);
});
btnSettings.setOnClickListener(v -> {
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);
});
findViewById(R.id.cardReservasHoje).setOnClickListener(v -> {
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);
});

View File

@@ -38,7 +38,6 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -89,23 +88,26 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
}
private void loadRestaurantRating() {
if (selectedRestaurant == null || selectedRestaurant.getEmail() == null) return;
if (selectedRestaurant == null || selectedRestaurant.getEmail() == null)
return;
String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_");
android.widget.TextView txtAvgRating = findViewById(R.id.txtAvgRating);
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)
.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
@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);
Integer count = snapshot.child("ratingCount").getValue(Integer.class);
if (avg != null && count != null && count > 0) {
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 {
txtAvgRating.setText("0.0");
txtTotalReviews.setText("(0 avaliações)");
@@ -113,44 +115,51 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
}
@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() {
String filter = getIntent().getStringExtra("category_filter");
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;
if (filter != null) {
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() {
@Override
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();
for (com.google.firebase.database.DataSnapshot ds : snapshot.getChildren()) {
String role = ds.child("role").getValue(String.class);
String accountType = ds.child("accountType").getValue(String.class);
if ("ADMIN".equalsIgnoreCase(role) || "ESTABELECIMENTO".equalsIgnoreCase(accountType)) {
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 cat = ds.child("category").getValue(String.class);
String logoUrl = ds.child("logoUrl").getValue(String.class);
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 -> {
selectedRestaurant = restaurant;
currentState = State.DETAILS;
@@ -161,8 +170,10 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
@Override
public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {
if (progressBar != null) progressBar.setVisibility(android.view.View.GONE);
android.widget.Toast.makeText(ExplorarRestaurantesActivity.this, "Erro ao carregar restaurantes.", android.widget.Toast.LENGTH_SHORT).show();
if (progressBar != null)
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) -> {
selectedDate = dayOfMonth + "/" + (month + 1) + "/" + year;
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 -> {
@@ -201,9 +213,11 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
}
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_");
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());
storageRef.putFile(imageUri).addOnSuccessListener(taskSnapshot -> {
@@ -212,17 +226,20 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("photos").child(encodedEmail)
.push().child("url").setValue(photoUrl).addOnCompleteListener(task -> {
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 -> {
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() {
if (selectedRestaurant == null || selectedRestaurant.getEmail() == null) return;
if (selectedRestaurant == null || selectedRestaurant.getEmail() == null)
return;
String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_");
android.view.View dialogView = getLayoutInflater().inflate(R.layout.dialog_reviews_list, null);
@@ -244,11 +261,13 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
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);
String currentUserEmail = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null ?
com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser().getEmail() : null;
String currentUserEmail = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null
? com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser().getEmail()
: null;
reviewsRef.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
@Override
@@ -259,8 +278,9 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
String text = dst.child("text").getValue(String.class);
String uEmail = dst.child("userEmail").getValue(String.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(
dst.getKey(), author, text, rating, uEmail);
@@ -292,7 +312,8 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
@Override
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) {
if (selectedRestaurant == null || selectedRestaurant.getEmail() == null) return;
if (selectedRestaurant == null || selectedRestaurant.getEmail() == null)
return;
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);
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);
});
}
@@ -316,7 +340,8 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reviews").child(encodedEmail)
.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
@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;
int count = 0;
for (com.google.firebase.database.DataSnapshot dst : snapshot.getChildren()) {
@@ -326,27 +351,31 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
count++;
}
}
double newAvg = count > 0 ? (totalRating / count) : 0.0;
java.util.Map<String, Object> updates = new java.util.HashMap<>();
updates.put("ratingAvg", newAvg);
updates.put("ratingCount", count);
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("users")
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("Restaurantes")
.child(encodedEmail).updateChildren(updates);
}
@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() {
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);
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.Button btnSubmit = dialogView.findViewById(R.id.btnSubmitReview);
android.widget.Button btnCancel = dialogView.findViewById(R.id.btnCancelReview);
@@ -356,7 +385,8 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
input.addTextChangedListener(new android.text.TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
@@ -366,33 +396,37 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
}
@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)
.setView(dialogView)
.create();
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
btnCancel.setOnClickListener(v -> dialog.dismiss());
btnSubmit.setOnClickListener(v -> {
float rating = (float) ratingBar.getRating();
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) {
String userDoc = currentUser.getEmail().replace(".", "_").replace("@", "_at_");
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("users").child(userDoc).get().addOnSuccessListener(snapshot -> {
String authorName = snapshot.exists() && snapshot.child("displayName").getValue(String.class) != null
? snapshot.child("displayName").getValue(String.class)
: "Visitante";
submitReviewToFirebase(authorName, revText, rating);
dialog.dismiss();
}).addOnFailureListener(e -> {
submitReviewToFirebase("Visitante", revText, rating);
dialog.dismiss();
});
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("Clientes").child(userDoc).get()
.addOnSuccessListener(snapshot -> {
String authorName = snapshot.exists()
&& snapshot.child("displayName").getValue(String.class) != null
? snapshot.child("displayName").getValue(String.class)
: "Visitante";
submitReviewToFirebase(authorName, revText, rating);
dialog.dismiss();
}).addOnFailureListener(e -> {
submitReviewToFirebase("Visitante", revText, rating);
dialog.dismiss();
});
} else {
submitReviewToFirebase("Visitante", revText, rating);
dialog.dismiss();
@@ -404,10 +438,11 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
private void submitReviewToFirebase(String authorName, String revText, float newRating) {
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;
// 1. Guardar a Review
java.util.Map<String, Object> review = new java.util.HashMap<>();
review.put("author", authorName);
@@ -419,32 +454,39 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reviews")
.child(encodedEmail).push().setValue(review).addOnCompleteListener(task -> {
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
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() {
@Override
public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) {
Double currentAvg = snapshot.child("ratingAvg").getValue(Double.class);
Integer currentCount = snapshot.child("ratingCount").getValue(Integer.class);
if (currentAvg == null) currentAvg = 0.0;
if (currentCount == null) currentCount = 0;
if (currentAvg == null)
currentAvg = 0.0;
if (currentCount == null)
currentCount = 0;
double newAvg = ((currentAvg * currentCount) + newRating) / (currentCount + 1);
java.util.Map<String, Object> updates = new java.util.HashMap<>();
updates.put("ratingAvg", newAvg);
updates.put("ratingCount", currentCount + 1);
restRef.updateChildren(updates);
}
@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;
try {
partySize = Integer.parseInt(etPartySize.getText().toString());
} catch (Exception e) {}
} catch (Exception e) {
}
if (selectedDate == null || selectedTime == null || partySize == 0) {
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);
progressBar = findViewById(R.id.progressBar);
emptyState = findViewById(R.id.emptyState);
list = new ArrayList<>();
adapter = new RestaurantAdapter(list, restaurant -> {
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();
if (user != null && user.getEmail() != null) {
String encodedUserEmail = user.getEmail().replace(".", "_").replace("@", "_at_");
DatabaseReference favRef = FirebaseDatabase.getInstance().getReference("users")
DatabaseReference favRef = FirebaseDatabase.getInstance().getReference("Clientes")
.child(encodedUserEmail).child("favorites");
favRef.addValueEventListener(new ValueEventListener() {
@Override
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();
for (DataSnapshot ds : snapshot.getChildren()) {
Restaurant restaurant = ds.getValue(Restaurant.class);
@@ -82,7 +83,7 @@ public class FavoritosActivity extends AppCompatActivity {
}
}
adapter.notifyDataSetChanged();
if (emptyState != null) {
emptyState.setVisibility(list.isEmpty() ? android.view.View.VISIBLE : android.view.View.GONE);
}
@@ -90,7 +91,8 @@ public class FavoritosActivity extends AppCompatActivity {
@Override
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();
}
});

View File

@@ -24,7 +24,8 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
private List<Restaurant> restaurants;
private RestaurantAdapter.OnRestaurantClickListener listener;
public FeaturedRestaurantAdapter(List<Restaurant> restaurants, RestaurantAdapter.OnRestaurantClickListener listener) {
public FeaturedRestaurantAdapter(List<Restaurant> restaurants,
RestaurantAdapter.OnRestaurantClickListener listener) {
this.restaurants = restaurants;
this.listener = listener;
}
@@ -41,15 +42,16 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
Restaurant restaurant = restaurants.get(position);
holder.txtName.setText(restaurant.getName());
holder.txtCategory.setText("" + restaurant.getCategory());
if (holder.txtRating != null) {
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 {
holder.txtRating.setText("Novo");
}
}
if (restaurant.getLogoUrl() != null && !restaurant.getLogoUrl().isEmpty()) {
com.bumptech.glide.Glide.with(holder.itemView.getContext())
.load(restaurant.getLogoUrl())
@@ -58,7 +60,7 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
} else {
holder.imgCover.setImageResource(R.mipmap.ic_launcher);
}
holder.itemView.setOnClickListener(v -> {
if (listener != null) {
listener.onRestaurantClick(restaurant);
@@ -70,7 +72,7 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
if (user != null && user.getEmail() != null && restaurant.getEmail() != null) {
String encodedUserEmail = user.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);
// Read initial state
@@ -80,7 +82,8 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
holder.btnFavorite.setTag(snapshot.exists());
if (snapshot.exists()) {
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 {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off);
holder.btnFavorite.clearColorFilter();
@@ -88,7 +91,8 @@ public class FeaturedRestaurantAdapter extends RecyclerView.Adapter<FeaturedRest
}
@Override
public void onCancelled(@NonNull DatabaseError error) { }
public void onCancelled(@NonNull DatabaseError error) {
}
});
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 newFavState = !isFav;
holder.btnFavorite.setTag(newFavState);
if (newFavState) {
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);
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 {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off);
holder.btnFavorite.clearColorFilter();
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;
ImageView imgCover;
android.widget.ImageButton btnFavorite;
public ViewHolder(@NonNull View itemView) {
super(itemView);
txtName = itemView.findViewById(R.id.txtFeaturedName);

View File

@@ -49,11 +49,10 @@ public class ListaEsperaActivity extends AppCompatActivity {
restaurantEmail = getIntent().getStringExtra(MainActivity.EXTRA_EMAIL);
if (restaurantEmail == null) {
// Se o extra não chegou, falha segura
if (com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null) {
restaurantEmail = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser().getEmail();
} 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();
setupPrimaryAction();
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() {
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);
}
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);
}
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);
}
}
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);
}
} 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);
}
}
@@ -140,7 +166,8 @@ public class MainActivity extends AppCompatActivity {
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.")
.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) -> {
permissionRequest.launch(permissionsNeeded.toArray(new String[0]));
})
@@ -164,47 +191,52 @@ public class MainActivity extends AppCompatActivity {
inputEstablishmentPhone = findViewById(R.id.inputEstablishmentPhone);
txtForgotPassword = findViewById(R.id.txtForgotPassword);
iconPasswordVisibility = findViewById(R.id.iconPasswordVisibility);
setupPasswordFeatures();
}
private void setupPasswordFeatures() {
iconPasswordVisibility.setOnClickListener(v -> {
isPasswordVisible = !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);
} 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);
}
inputPassword.setSelection(inputPassword.getText().length());
});
txtForgotPassword.setOnClickListener(v -> {
String email = inputEmail.getText().toString().trim();
if (TextUtils.isEmpty(email)) {
Toast.makeText(this, "Por favor, introduza o seu email primeiro.", Toast.LENGTH_SHORT).show();
return;
}
new AlertDialog.Builder(this)
.setTitle("Recuperar palavra-passe")
.setMessage("Deseja enviar um email de recuperação para " + email + "?")
.setPositiveButton("Sim", (dialog, which) -> {
if (firebaseAuth != null) {
firebaseAuth.sendPasswordResetEmail(email)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Toast.makeText(MainActivity.this, "Email de recuperação enviado!", 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();
.setTitle("Recuperar palavra-passe")
.setMessage("Deseja enviar um email de recuperação para " + email + "?")
.setPositiveButton("Sim", (dialog, which) -> {
if (firebaseAuth != null) {
firebaseAuth.sendPasswordResetEmail(email)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Toast.makeText(MainActivity.this, "Email de recuperação enviado!",
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();
});
}
@@ -274,7 +306,7 @@ public class MainActivity extends AppCompatActivity {
inputEstablishmentName.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE);
inputEstablishmentEmail.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE);
inputEstablishmentPhone.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE);
if (txtForgotPassword != null) {
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) {
if (databaseReference == null) {
Toast.makeText(this, "Firebase indisponível.", Toast.LENGTH_SHORT).show();
navigateToDashboard(email, fallbackName, resolvedRole);
if (firebaseAuth != null) firebaseAuth.signOut();
return;
}
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()) {
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();
navigateToDashboard(email, fallbackName, resolvedRole);
if (firebaseAuth != null) firebaseAuth.signOut();
return;
}
DataSnapshot snapshot = task.getResult();
if (snapshot == null || !snapshot.exists()) {
// Toast.makeText(this, "Conta sem perfil na cloud. A entrar em modo básico.",
// Toast.LENGTH_SHORT).show();
navigateToDashboard(email, fallbackName, resolvedRole);
String tipo = selectedAccountType == AccountType.ESTABELECIMENTO ? "Estabelecimento" : "Cliente";
Toast.makeText(this, "Conta não encontrada como " + tipo + ".\nPor favor, crie uma conta nova.", Toast.LENGTH_LONG).show();
if (firebaseAuth != null) firebaseAuth.signOut();
return;
}
String accountTypeInFirebase = snapshot.child("accountType").getValue(String.class);
if (accountTypeInFirebase != null
&& !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();
if (firebaseAuth != null) firebaseAuth.signOut();
return;
}
@@ -533,7 +567,8 @@ public class MainActivity extends AppCompatActivity {
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 -> {
Toast.makeText(this, "Conta guardada na cloud.", Toast.LENGTH_SHORT).show();
if (onSuccess != null) {

View File

@@ -102,7 +102,7 @@ public class NovaReservaActivity extends AppCompatActivity {
private void setupRestaurants() {
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
.getInstance().getReference("users");
.getInstance().getReference("Restaurantes");
if (progressBar != null)
progressBar.setVisibility(android.view.View.VISIBLE);

View File

@@ -53,7 +53,7 @@ public class ProfileDashboardActivity extends AppCompatActivity {
documentId = email.replace(".", "_").replace("@", "_at_");
}
databaseReference = FirebaseDatabase.getInstance().getReference().child("users");
databaseReference = FirebaseDatabase.getInstance().getReference().child("Clientes");
inputName = findViewById(R.id.inputProfileName);
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) {
Restaurant restaurant = restaurants.get(position);
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 (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 {
holder.txtRating.setText("Novo");
}
}
if (restaurant.getLogoUrl() != null && !restaurant.getLogoUrl().isEmpty()) {
com.bumptech.glide.Glide.with(holder.itemView.getContext())
.load(restaurant.getLogoUrl())
@@ -63,7 +65,7 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
} else {
holder.imgThumb.setImageResource(R.mipmap.ic_launcher);
}
holder.itemView.setOnClickListener(v -> {
if (listener != null) {
listener.onRestaurantClick(restaurant);
@@ -82,7 +84,7 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
if (user != null && user.getEmail() != null && restaurant.getEmail() != null) {
String encodedUserEmail = user.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);
// Read initial state
@@ -92,7 +94,8 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
holder.btnFavorite.setTag(snapshot.exists());
if (snapshot.exists()) {
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 {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off);
holder.btnFavorite.clearColorFilter();
@@ -100,7 +103,8 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
}
@Override
public void onCancelled(@NonNull DatabaseError error) { }
public void onCancelled(@NonNull DatabaseError error) {
}
});
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 newFavState = !isFav;
holder.btnFavorite.setTag(newFavState);
if (newFavState) {
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);
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 {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off);
holder.btnFavorite.clearColorFilter();
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;
android.widget.ImageView imgThumb;
Button btnReservar;
public ViewHolder(@NonNull View itemView) {
super(itemView);
text1 = itemView.findViewById(R.id.txtRestaurantName);