From 404f28da1520933d174e0a96a71de72bdd2a6d75 Mon Sep 17 00:00:00 2001
From: 230409 <230409@epvc.pt>
Date: Thu, 16 Apr 2026 10:34:55 +0100
Subject: [PATCH] ...
---
app/src/main/AndroidManifest.xml | 3 +
.../example/pap_teste/AddStaffActivity.java | 5 +
.../pap_teste/ClientDashboardActivity.java | 113 ++++++++++-
.../pap_teste/DefinicoesAdminActivity.java | 2 +-
.../pap_teste/DetalhesReservasActivity.java | 44 ++--
.../EstablishmentDashboardActivity.java | 81 +++++++-
.../ExplorarRestaurantesActivity.java | 66 +++---
.../pap_teste/GestaoStaffActivity.java | 37 ++++
.../pap_teste/ListaEsperaActivity.java | 71 ++++++-
.../com/example/pap_teste/MainActivity.java | 12 +-
.../main/res/layout/activity_add_staff.xml | 190 ++++++++++++------
.../activity_establishment_dashboard.xml | 11 +-
.../main/res/layout/activity_gestao_staff.xml | 10 +
13 files changed, 527 insertions(+), 118 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a818cc4..b1b9e33 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,6 +5,9 @@
+
+
+
diff --git a/app/src/main/java/com/example/pap_teste/AddStaffActivity.java b/app/src/main/java/com/example/pap_teste/AddStaffActivity.java
index eff9f1b..dba5c09 100644
--- a/app/src/main/java/com/example/pap_teste/AddStaffActivity.java
+++ b/app/src/main/java/com/example/pap_teste/AddStaffActivity.java
@@ -50,6 +50,11 @@ public class AddStaffActivity extends AppCompatActivity {
zonaSpinner = findViewById(R.id.zonaSpinner);
btnAddZone = findViewById(R.id.btnAddZone);
mesaSpinner = findViewById(R.id.mesaSpinner);
+
+ Button btnVoltarAddStaff = findViewById(R.id.btnVoltarAddStaff);
+ if (btnVoltarAddStaff != null) {
+ btnVoltarAddStaff.setOnClickListener(v -> finish());
+ }
zones = new ArrayList<>();
zones.add("Sala");
diff --git a/app/src/main/java/com/example/pap_teste/ClientDashboardActivity.java b/app/src/main/java/com/example/pap_teste/ClientDashboardActivity.java
index 5ef1152..b255033 100644
--- a/app/src/main/java/com/example/pap_teste/ClientDashboardActivity.java
+++ b/app/src/main/java/com/example/pap_teste/ClientDashboardActivity.java
@@ -56,6 +56,7 @@ public class ClientDashboardActivity extends AppCompatActivity {
fetchProfilePicture();
setupCategories();
setupActions();
+ loadNextReservation();
}
private void updateGreeting() {
@@ -106,17 +107,6 @@ public class ClientDashboardActivity extends AppCompatActivity {
findViewById(R.id.btnVoltar).setOnClickListener(v -> finish());
- findViewById(R.id.btnCheckIn).setOnClickListener(v -> {
- boolean hasLocationPermission = androidx.core.app.ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == android.content.pm.PackageManager.PERMISSION_GRANTED;
- if (!hasLocationPermission) {
- android.widget.Toast.makeText(this, "Dê permissões de localização para aceder ao check-in.", android.widget.Toast.LENGTH_SHORT).show();
- } else {
- Intent intent = new Intent(this, CheckInAntecipadoActivity.class);
- intent.putExtra("restaurant_email", "sabor_arte@restaurante.com");
- startActivity(intent);
- }
- });
-
findViewById(R.id.btnPartilhar).setOnClickListener(
v -> startActivity(new Intent(this, PartilharReservaActivity.class)));
@@ -130,4 +120,105 @@ public class ClientDashboardActivity extends AppCompatActivity {
startActivity(intent);
});
}
+
+ private void loadNextReservation() {
+ if (email == null) return;
+ com.google.firebase.database.DatabaseReference ref = com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reservas");
+ ref.orderByChild("clienteEmail").equalTo(email).addValueEventListener(new com.google.firebase.database.ValueEventListener() {
+ @Override
+ public void onDataChange(com.google.firebase.database.DataSnapshot snapshot) {
+ com.example.pap_teste.models.Reserva proxima = null;
+ long timeProx = Long.MAX_VALUE;
+ long currentTime = System.currentTimeMillis();
+ java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm", java.util.Locale.getDefault());
+
+ for (com.google.firebase.database.DataSnapshot ds : snapshot.getChildren()) {
+ com.example.pap_teste.models.Reserva r = ds.getValue(com.example.pap_teste.models.Reserva.class);
+ if (r != null && (r.getEstado().startsWith("Confirmada") || r.getEstado().equals("Pendente"))) {
+ try {
+ java.util.Date rDate = sdf.parse(r.getData() + " " + r.getHora());
+ if (rDate != null) {
+ long rTime = rDate.getTime();
+ // Consider reservations from the last 2 hours and in the future
+ if (rTime >= currentTime - 2L * 60 * 60 * 1000) {
+ if (rTime < timeProx) {
+ timeProx = rTime;
+ proxima = r;
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ TextView txtTitle = findViewById(R.id.txtResTitle);
+ TextView txtTime = findViewById(R.id.txtResTime);
+ Button btnCheckIn = findViewById(R.id.btnCheckIn);
+ Button btnPartilhar = findViewById(R.id.btnPartilhar);
+
+ if (proxima != null) {
+ txtTitle.setText(proxima.getRestauranteName());
+
+ // Formatting to show "Hoje", "Amanhã" or the date itself
+ String dateStr = proxima.getData();
+ try {
+ java.util.Date rDate = sdf.parse(proxima.getData() + " " + proxima.getHora());
+ if (rDate != null) {
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ cal.setTime(rDate);
+
+ java.util.Calendar today = java.util.Calendar.getInstance();
+
+ java.util.Calendar tmr = java.util.Calendar.getInstance();
+ tmr.add(java.util.Calendar.DAY_OF_YEAR, 1);
+
+ if (cal.get(java.util.Calendar.YEAR) == today.get(java.util.Calendar.YEAR) && cal.get(java.util.Calendar.DAY_OF_YEAR) == today.get(java.util.Calendar.DAY_OF_YEAR)) {
+ dateStr = "Hoje";
+ } else if (cal.get(java.util.Calendar.YEAR) == tmr.get(java.util.Calendar.YEAR) && cal.get(java.util.Calendar.DAY_OF_YEAR) == tmr.get(java.util.Calendar.DAY_OF_YEAR)) {
+ dateStr = "Amanhã";
+ }
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+
+ txtTime.setText(String.format("%s às %s • %d pessoas", dateStr, proxima.getHora(), proxima.getPessoas()));
+ btnCheckIn.setVisibility(android.view.View.VISIBLE);
+ btnPartilhar.setVisibility(android.view.View.VISIBLE);
+
+ String encodedEmail = proxima.getRestauranteEmail().replace(".", "_").replace("@", "_at_");
+ com.google.firebase.database.FirebaseDatabase.getInstance().getReference("users").child(encodedEmail)
+ .child("logoUrl").get().addOnSuccessListener(s -> {
+ if (!isDestroyed() && s.exists() && s.getValue() != null) {
+ android.widget.ImageView imgResIcon = findViewById(R.id.imgResIcon);
+ com.bumptech.glide.Glide.with(ClientDashboardActivity.this).load(s.getValue(String.class)).circleCrop().into(imgResIcon);
+ }
+ });
+
+ com.example.pap_teste.models.Reserva finalProxima = proxima;
+ btnCheckIn.setOnClickListener(v -> {
+ boolean hasLocationPermission = androidx.core.app.ActivityCompat.checkSelfPermission(ClientDashboardActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) == android.content.pm.PackageManager.PERMISSION_GRANTED;
+ if (!hasLocationPermission) {
+ android.widget.Toast.makeText(ClientDashboardActivity.this, "Dê permissões de localização para aceder ao check-in.", android.widget.Toast.LENGTH_SHORT).show();
+ } else {
+ Intent intent = new Intent(ClientDashboardActivity.this, CheckInAntecipadoActivity.class);
+ intent.putExtra("restaurant_email", finalProxima.getRestauranteEmail());
+ startActivity(intent);
+ }
+ });
+ } else {
+ txtTitle.setText("Sem reservas ativas");
+ txtTime.setText("Explore os restaurantes e reserve!");
+ btnCheckIn.setVisibility(android.view.View.GONE);
+ btnPartilhar.setVisibility(android.view.View.GONE);
+ android.widget.ImageView imgResIcon = findViewById(R.id.imgResIcon);
+ imgResIcon.setImageResource(R.drawable.circle_bg);
+ }
+ }
+ @Override
+ public void onCancelled(com.google.firebase.database.DatabaseError error) {}
+ });
+ }
}
diff --git a/app/src/main/java/com/example/pap_teste/DefinicoesAdminActivity.java b/app/src/main/java/com/example/pap_teste/DefinicoesAdminActivity.java
index 061cb28..ce9640e 100644
--- a/app/src/main/java/com/example/pap_teste/DefinicoesAdminActivity.java
+++ b/app/src/main/java/com/example/pap_teste/DefinicoesAdminActivity.java
@@ -210,7 +210,7 @@ public class DefinicoesAdminActivity extends AppCompatActivity {
updates.put("address", addressStr);
updates.put("category", selectedCategory);
if (photoUrl != null) {
- updates.put("logoUrl", photoUrl);
+ updates.put("logoUrl", photoUrl);
}
databaseReference.child(documentId).updateChildren(updates)
diff --git a/app/src/main/java/com/example/pap_teste/DetalhesReservasActivity.java b/app/src/main/java/com/example/pap_teste/DetalhesReservasActivity.java
index 79fc1ad..51d223e 100644
--- a/app/src/main/java/com/example/pap_teste/DetalhesReservasActivity.java
+++ b/app/src/main/java/com/example/pap_teste/DetalhesReservasActivity.java
@@ -79,7 +79,7 @@ public class DetalhesReservasActivity extends AppCompatActivity {
for (com.google.firebase.database.DataSnapshot data : snapshot.getChildren()) {
com.example.pap_teste.models.Reserva r = data
.getValue(com.example.pap_teste.models.Reserva.class);
- if (r != null) {
+ if (r != null && r.getEstado() != null && !"Arquivada".equals(r.getEstado())) {
reservas.add(r);
}
}
@@ -145,25 +145,39 @@ public class DetalhesReservasActivity extends AppCompatActivity {
return;
new androidx.appcompat.app.AlertDialog.Builder(this)
- .setTitle("Apagar Reserva")
- .setMessage("Tem a certeza que deseja apagar esta reserva?")
- .setPositiveButton("Apagar", (dialog, which) -> {
- String idReserva = reservas.get(selectedIndex).getId();
- databaseReference.child(idReserva).removeValue().addOnCompleteListener(task -> {
- if (task.isSuccessful()) {
- selectedIndex = -1;
- txtInfo.setText("Selecione uma reserva");
- txtNotas.setText("");
- txtEstado.setText("Estado:");
- txtMensagem.setText("Reserva apagada com sucesso.");
- toggleButtons(null);
- }
- });
+ .setTitle("Apagar/Arquivar Reserva")
+ .setMessage("Tem a certeza que deseja limpar esta reserva da lista?")
+ .setPositiveButton("Sim", (dialog, which) -> {
+ com.example.pap_teste.models.Reserva r = reservas.get(selectedIndex);
+ String idReserva = r.getId();
+
+ if ("Concluída".equals(r.getEstado()) || r.getEstado().startsWith("Confirmada")) {
+ databaseReference.child(idReserva).child("estado").setValue("Arquivada").addOnCompleteListener(task -> {
+ if (task.isSuccessful()) {
+ clearSelectionAndShowMessage();
+ }
+ });
+ } else {
+ databaseReference.child(idReserva).removeValue().addOnCompleteListener(task -> {
+ if (task.isSuccessful()) {
+ clearSelectionAndShowMessage();
+ }
+ });
+ }
})
.setNegativeButton("Voltar", null)
.show();
}
+ private void clearSelectionAndShowMessage() {
+ selectedIndex = -1;
+ txtInfo.setText("Selecione uma reserva");
+ txtNotas.setText("");
+ txtEstado.setText("Estado:");
+ txtMensagem.setText("Reserva processada e apagada da vista.");
+ toggleButtons(null);
+ }
+
private void atualizarEstadoSelecionado(String novoEstado) {
if (selectedIndex < 0 || selectedIndex >= reservas.size()) {
Toast.makeText(this, "Selecione uma reserva para atualizar.", Toast.LENGTH_SHORT).show();
diff --git a/app/src/main/java/com/example/pap_teste/EstablishmentDashboardActivity.java b/app/src/main/java/com/example/pap_teste/EstablishmentDashboardActivity.java
index 30d007d..927dc96 100644
--- a/app/src/main/java/com/example/pap_teste/EstablishmentDashboardActivity.java
+++ b/app/src/main/java/com/example/pap_teste/EstablishmentDashboardActivity.java
@@ -64,12 +64,19 @@ public class EstablishmentDashboardActivity extends AppCompatActivity {
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));
+ startActivity(intent);
+ });
+
if (btnBack != null) {
btnBack.setOnClickListener(v -> finish());
}
loadProximasReservas();
+ loadEstatisticas();
}
private void loadProximasReservas() {
@@ -83,6 +90,11 @@ public class EstablishmentDashboardActivity extends AppCompatActivity {
}
}
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ String todayDate = cal.get(java.util.Calendar.DAY_OF_MONTH) + "/" +
+ (cal.get(java.util.Calendar.MONTH) + 1) + "/" +
+ cal.get(java.util.Calendar.YEAR);
+
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reservas")
.orderByChild("restauranteEmail").equalTo(email)
.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
@@ -93,7 +105,7 @@ public class EstablishmentDashboardActivity extends AppCompatActivity {
for (com.google.firebase.database.DataSnapshot ds : snapshot.getChildren()) {
com.example.pap_teste.models.Reserva r = ds.getValue(com.example.pap_teste.models.Reserva.class);
- if (r != null && "Confirmada".equals(r.getEstado())) {
+ if (r != null && r.getEstado() != null && (r.getEstado().startsWith("Confirmada") || r.getEstado().equals("Concluída")) && todayDate.equals(r.getData())) {
found = true;
addReservaView(llProximasReservas, r);
}
@@ -141,4 +153,71 @@ public class EstablishmentDashboardActivity extends AppCompatActivity {
container.addView(subtitle);
container.addView(divider);
}
+
+ private void loadEstatisticas() {
+ TextView txtReservasHoje = findViewById(R.id.txtReservasHojeDash);
+ TextView txtMesasLivres = findViewById(R.id.txtMesasLivresDash);
+ TextView txtListaEspera = findViewById(R.id.txtListaEsperaDash);
+
+ 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;
+ }
+ }
+ final String finalEmail = email;
+
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ String todayDate = cal.get(java.util.Calendar.DAY_OF_MONTH) + "/" +
+ (cal.get(java.util.Calendar.MONTH) + 1) + "/" +
+ cal.get(java.util.Calendar.YEAR);
+
+ com.google.firebase.database.DatabaseReference refReservas = com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reservas");
+ refReservas.orderByChild("restauranteEmail").equalTo(finalEmail)
+ .addValueEventListener(new com.google.firebase.database.ValueEventListener() {
+ @Override
+ public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) {
+ int reservasHoje = 0;
+ int listaEspera = 0;
+ for (com.google.firebase.database.DataSnapshot ds : snapshot.getChildren()) {
+ com.example.pap_teste.models.Reserva r = ds.getValue(com.example.pap_teste.models.Reserva.class);
+ if (r != null && r.getEstado() != null) {
+ if ((r.getEstado().startsWith("Confirmada") || r.getEstado().equals("Concluída") || r.getEstado().equals("Arquivada")) && todayDate.equals(r.getData())) {
+ reservasHoje++;
+ } else if ("Pendente".equals(r.getEstado())) {
+ listaEspera++;
+ }
+ }
+ }
+ if (txtReservasHoje != null) txtReservasHoje.setText(String.format(java.util.Locale.US, "%02d", reservasHoje));
+ if (txtListaEspera != null) txtListaEspera.setText(String.format(java.util.Locale.US, "%02d", listaEspera));
+ }
+
+ @Override
+ public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {
+ }
+ });
+
+ com.google.firebase.database.FirebaseDatabase.getInstance().getReference("Mesas")
+ .addValueEventListener(new com.google.firebase.database.ValueEventListener() {
+ @Override
+ public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) {
+ int mesasLivres = 0;
+ for (com.google.firebase.database.DataSnapshot ds : snapshot.getChildren()) {
+ com.example.pap_teste.models.Mesa mesa = ds.getValue(com.example.pap_teste.models.Mesa.class);
+ if (mesa != null && finalEmail.equals(mesa.getRestauranteEmail())) {
+ if ("Livre".equalsIgnoreCase(mesa.getEstado())) {
+ mesasLivres++;
+ }
+ }
+ }
+ if (txtMesasLivres != null) txtMesasLivres.setText(String.format(java.util.Locale.US, "%02d", mesasLivres));
+ }
+ @Override
+ public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {
+ }
+ });
+ }
}
diff --git a/app/src/main/java/com/example/pap_teste/ExplorarRestaurantesActivity.java b/app/src/main/java/com/example/pap_teste/ExplorarRestaurantesActivity.java
index 2345a0d..568eded 100644
--- a/app/src/main/java/com/example/pap_teste/ExplorarRestaurantesActivity.java
+++ b/app/src/main/java/com/example/pap_teste/ExplorarRestaurantesActivity.java
@@ -26,6 +26,17 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
private String selectedDate = null;
private String selectedTime = null;
+ private final androidx.activity.result.ActivityResultLauncher photoPickerLauncher = registerForActivityResult(
+ new androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult(),
+ result -> {
+ if (result.getResultCode() == RESULT_OK && result.getData() != null) {
+ android.net.Uri imageUri = result.getData().getData();
+ if (imageUri != null) {
+ uploadRestaurantPhoto(imageUri);
+ }
+ }
+ });
+
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -119,7 +130,6 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
}
});
}
- private androidx.activity.result.ActivityResultLauncher photoPickerLauncher;
private void setupReservationOptions() {
android.widget.Button btnDate = findViewById(R.id.btnSelectDate);
@@ -147,19 +157,6 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
btnVerAvaliacoes.setOnClickListener(v -> showReviewsDialog());
- if (photoPickerLauncher == null) {
- photoPickerLauncher = registerForActivityResult(
- new androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult(),
- result -> {
- if (result.getResultCode() == RESULT_OK && result.getData() != null) {
- android.net.Uri imageUri = result.getData().getData();
- if (imageUri != null) {
- uploadRestaurantPhoto(imageUri);
- }
- }
- });
- }
-
btnUploadFoto.setOnClickListener(v -> {
android.content.Intent intent = new android.content.Intent(android.content.Intent.ACTION_PICK);
intent.setType("image/*");
@@ -238,27 +235,38 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
.setPositiveButton("Enviar", (dialog, which) -> {
String revText = input.getText().toString().trim();
if (!revText.isEmpty()) {
- String userEmail = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null
- ? com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser().getEmail()
- : "Visitante";
-
- String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_");
- java.util.Map review = new java.util.HashMap<>();
- review.put("author", userEmail);
- review.put("text", revText);
-
- com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reviews")
- .child(encodedEmail).push().setValue(review).addOnCompleteListener(task -> {
- if (task.isSuccessful()) {
- android.widget.Toast.makeText(this, "Avaliação enviada!", android.widget.Toast.LENGTH_SHORT).show();
- }
- });
+ 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);
+ }).addOnFailureListener(e -> submitReviewToFirebase("Visitante", revText));
+ } else {
+ submitReviewToFirebase("Visitante", revText);
+ }
}
})
.setNegativeButton("Cancelar", null)
.show();
}
+ private void submitReviewToFirebase(String authorName, String revText) {
+ String encodedEmail = selectedRestaurant.getEmail().replace(".", "_").replace("@", "_at_");
+ java.util.Map review = new java.util.HashMap<>();
+ review.put("author", authorName);
+ review.put("text", revText);
+
+ com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reviews")
+ .child(encodedEmail).push().setValue(review).addOnCompleteListener(task -> {
+ if (task.isSuccessful()) {
+ android.widget.Toast.makeText(this, "Avaliação enviada!", android.widget.Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
private void saveReservation() {
android.widget.EditText etPartySize = findViewById(R.id.etPartySize);
int partySize = 0;
diff --git a/app/src/main/java/com/example/pap_teste/GestaoStaffActivity.java b/app/src/main/java/com/example/pap_teste/GestaoStaffActivity.java
index f82deed..2082f37 100644
--- a/app/src/main/java/com/example/pap_teste/GestaoStaffActivity.java
+++ b/app/src/main/java/com/example/pap_teste/GestaoStaffActivity.java
@@ -160,6 +160,11 @@ public class GestaoStaffActivity extends AppCompatActivity {
btnAtribuir.setOnClickListener(v -> guardarAtribuicao());
}
+ Button btnEliminar = findViewById(R.id.btnEliminarStaff);
+ if (btnEliminar != null) {
+ btnEliminar.setOnClickListener(v -> eliminarStaff());
+ }
+
if (floatingActionButton != null) {
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
@@ -216,6 +221,38 @@ public class GestaoStaffActivity extends AppCompatActivity {
}
}
+ private void eliminarStaff() {
+ String nome = "";
+ if (spinnerNomeStaff.getSelectedItem() != null) {
+ nome = spinnerNomeStaff.getSelectedItem().toString();
+ }
+
+ if (nome.isEmpty()) {
+ Toast.makeText(this, "Selecione um funcionário primeiro.", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ Staff staffToDelete = findByNome(nome);
+ if (staffToDelete != null) {
+ new androidx.appcompat.app.AlertDialog.Builder(this)
+ .setTitle("Eliminar Staff")
+ .setMessage("Tem a certeza que deseja eliminar o funcionário " + staffToDelete.getName() + "?")
+ .setPositiveButton("Eliminar", (dialog, which) -> {
+ staffRef.child(staffToDelete.getId()).removeValue()
+ .addOnSuccessListener(aVoid -> {
+ txtMensagemStaff.setText(staffToDelete.getName() + " foi eliminado.");
+ })
+ .addOnFailureListener(e -> {
+ Toast.makeText(this, "Erro ao eliminar: " + e.getMessage(), Toast.LENGTH_SHORT).show();
+ });
+ })
+ .setNegativeButton("Cancelar", null)
+ .show();
+ } else {
+ Toast.makeText(this, "Staff não encontrado.", Toast.LENGTH_SHORT).show();
+ }
+ }
+
private Staff findByNome(String nome) {
for (Staff item : staffList) {
if (item.getName().equalsIgnoreCase(nome)) {
diff --git a/app/src/main/java/com/example/pap_teste/ListaEsperaActivity.java b/app/src/main/java/com/example/pap_teste/ListaEsperaActivity.java
index 634962a..40c2e79 100644
--- a/app/src/main/java/com/example/pap_teste/ListaEsperaActivity.java
+++ b/app/src/main/java/com/example/pap_teste/ListaEsperaActivity.java
@@ -88,10 +88,79 @@ public class ListaEsperaActivity extends AppCompatActivity {
}
private void setupActions() {
- btnConfirmar.setOnClickListener(v -> atualizarEstadoSelecionado("Confirmada"));
+ btnConfirmar.setOnClickListener(v -> mostrarMesasDisponiveis());
btnRecusar.setOnClickListener(v -> showRecusarDialog());
}
+ private void mostrarMesasDisponiveis() {
+ if (selectedIndex < 0 || selectedIndex >= reservasPendentes.size()) {
+ Toast.makeText(this, "Selecione uma reserva.", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ Reserva item = reservasPendentes.get(selectedIndex);
+
+ DatabaseReference mesasRef = FirebaseDatabase.getInstance().getReference("Mesas");
+ mesasRef.orderByChild("restauranteEmail").equalTo(restaurantEmail).addListenerForSingleValueEvent(new ValueEventListener() {
+ @Override
+ public void onDataChange(@androidx.annotation.NonNull DataSnapshot snapshot) {
+ List mesasLivres = new ArrayList<>();
+ for (DataSnapshot ds : snapshot.getChildren()) {
+ com.example.pap_teste.models.Mesa m = ds.getValue(com.example.pap_teste.models.Mesa.class);
+ if (m != null && m.getEstado() != null && m.getEstado().equalsIgnoreCase("Livre")) {
+ m.setId(ds.getKey());
+ mesasLivres.add(m);
+ }
+ }
+
+ if (mesasLivres.isEmpty()) {
+ new androidx.appcompat.app.AlertDialog.Builder(ListaEsperaActivity.this)
+ .setTitle("Sem mesas disponíveis")
+ .setMessage("Não há mesas livres registadas. Deseja confirmar a reserva mesmo assim (sem lugar reservado)?")
+ .setPositiveButton("Sim", (dialog, which) -> atualizarEstadoSelecionado("Confirmada"))
+ .setNegativeButton("Não", null)
+ .show();
+ return;
+ }
+
+ String[] mesaOptions = new String[mesasLivres.size()];
+ for (int i = 0; i < mesasLivres.size(); i++) {
+ com.example.pap_teste.models.Mesa m = mesasLivres.get(i);
+ mesaOptions[i] = String.format("Mesa %d (%d lugares)", m.getNumero(), m.getCapacidade());
+ }
+
+ new androidx.appcompat.app.AlertDialog.Builder(ListaEsperaActivity.this)
+ .setTitle("Atribuir Mesa")
+ .setItems(mesaOptions, (dialog, which) -> {
+ com.example.pap_teste.models.Mesa selecionada = mesasLivres.get(which);
+ confirmarReservaComMesa(item, selecionada);
+ })
+ .setNegativeButton("Cancelar", null)
+ .show();
+ }
+
+ @Override
+ public void onCancelled(@androidx.annotation.NonNull DatabaseError error) {
+ Toast.makeText(ListaEsperaActivity.this, "Erro ao carregar mesas.", Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
+ private void confirmarReservaComMesa(Reserva reserva, com.example.pap_teste.models.Mesa mesa) {
+ String novoEstado = "Confirmada (Mesa " + mesa.getNumero() + ")";
+ databaseReference.child(reserva.getId()).child("estado").setValue(novoEstado).addOnCompleteListener(task -> {
+ if (task.isSuccessful()) {
+ FirebaseDatabase.getInstance().getReference("Mesas").child(mesa.getId()).child("estado").setValue("Reservada")
+ .addOnCompleteListener(t2 -> {
+ Toast.makeText(this, "Reserva aceite e mesa atribuída com sucesso.", Toast.LENGTH_SHORT).show();
+ selectedIndex = -1;
+ toggleButtons(null);
+ });
+ } else {
+ Toast.makeText(this, "Erro ao confirmar reserva.", Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
private void showRecusarDialog() {
if (selectedIndex < 0) return;
diff --git a/app/src/main/java/com/example/pap_teste/MainActivity.java b/app/src/main/java/com/example/pap_teste/MainActivity.java
index 405a7e5..2e10c54 100644
--- a/app/src/main/java/com/example/pap_teste/MainActivity.java
+++ b/app/src/main/java/com/example/pap_teste/MainActivity.java
@@ -127,10 +127,20 @@ public class MainActivity extends AppCompatActivity {
}
}
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ 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) {
+ permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+ }
+ }
+
if (!permissionsNeeded.isEmpty()) {
new AlertDialog.Builder(this)
.setTitle("Permissões Necessárias")
- .setMessage("Para o correto funcionamento do check-in e serviços de proximidade, 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]));
})
diff --git a/app/src/main/res/layout/activity_add_staff.xml b/app/src/main/res/layout/activity_add_staff.xml
index 4134ad9..8faf208 100644
--- a/app/src/main/res/layout/activity_add_staff.xml
+++ b/app/src/main/res/layout/activity_add_staff.xml
@@ -5,69 +5,147 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="#F7F7F7"
tools:context=".AddStaffActivity">
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_marginTop="20dp"
+ android:text="Novo Funcionário"
+ android:textColor="#000"
+ android:textSize="24sp"
+ android:textStyle="bold"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/btnVoltarAddStaff" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_establishment_dashboard.xml b/app/src/main/res/layout/activity_establishment_dashboard.xml
index d533c6f..b461873 100644
--- a/app/src/main/res/layout/activity_establishment_dashboard.xml
+++ b/app/src/main/res/layout/activity_establishment_dashboard.xml
@@ -69,10 +69,12 @@
android:orientation="horizontal">
@@ -92,10 +94,11 @@
android:textSize="12sp" />
@@ -127,10 +130,11 @@
android:textSize="12sp" />
@@ -161,10 +165,11 @@
android:textSize="12sp" />
diff --git a/app/src/main/res/layout/activity_gestao_staff.xml b/app/src/main/res/layout/activity_gestao_staff.xml
index 7ac3943..b65d259 100644
--- a/app/src/main/res/layout/activity_gestao_staff.xml
+++ b/app/src/main/res/layout/activity_gestao_staff.xml
@@ -91,6 +91,16 @@
android:textAllCaps="false"
android:textColor="#FFFFFF" />
+
+