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"> - +