...
This commit is contained in:
@@ -5,6 +5,9 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||
|
||||
<!-- Bluetooth permissions for energy/power stats and location accuracy -->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,17 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
|
||||
private String selectedDate = null;
|
||||
private String selectedTime = null;
|
||||
|
||||
private final androidx.activity.result.ActivityResultLauncher<android.content.Intent> 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<android.content.Intent> 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<String, Object> 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<String, Object> 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;
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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<com.example.pap_teste.models.Mesa> 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;
|
||||
|
||||
|
||||
@@ -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]));
|
||||
})
|
||||
|
||||
@@ -5,69 +5,147 @@
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F7F7F7"
|
||||
tools:context=".AddStaffActivity">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/nammeEditText"
|
||||
android:layout_width="0dp"
|
||||
<!-- Top Bar with Back Button -->
|
||||
<Button
|
||||
android:id="@+id/btnVoltarAddStaff"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:ems="10"
|
||||
android:hint="Name"
|
||||
android:inputType="text"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:text="Voltar"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="#FF5252"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/zoneLayout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="@+id/nammeEditText"
|
||||
app:layout_constraintStart_toStartOf="@+id/nammeEditText"
|
||||
app:layout_constraintTop_toBottomOf="@+id/nammeEditText">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/zonaSpinner"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:minHeight="48dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnAddZone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="+" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/mesaLayout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="@+id/zoneLayout"
|
||||
app:layout_constraintStart_toStartOf="@+id/zoneLayout"
|
||||
app:layout_constraintTop_toBottomOf="@+id/zoneLayout">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/mesaSpinner"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:minHeight="48dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/addButton"
|
||||
<TextView
|
||||
android:id="@+id/txtAdicionarTitulo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Button"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
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" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtAdicionarDesc"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Introduza os dados e atribuições deste membro:"
|
||||
android:textColor="#666666"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/txtAdicionarTitulo" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:background="#FFFFFF"
|
||||
android:elevation="2dp"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/txtAdicionarDesc">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Nome do Funcionário"
|
||||
android:textColor="#333"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/nammeEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/input_bg"
|
||||
android:hint="Ex: João Silva"
|
||||
android:inputType="textPersonName"
|
||||
android:paddingHorizontal="16dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="Zona de Trabalho"
|
||||
android:textColor="#333"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/zoneLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/zonaSpinner"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/input_bg" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnAddZone"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="@drawable/btn_primary"
|
||||
android:text="+"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="Mesa a Atribuir"
|
||||
android:textColor="#333"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/mesaLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/mesaSpinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:background="@drawable/input_bg" />
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/addButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:background="@drawable/btn_primary"
|
||||
android:text="Adicionar Membro"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -69,10 +69,12 @@
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cardReservasHoje"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_weight="1"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
app:cardBackgroundColor="#FFFFFF"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="3dp">
|
||||
@@ -92,10 +94,11 @@
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtReservasHojeDash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="32"
|
||||
android:text="00"
|
||||
android:textColor="#000"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold" />
|
||||
@@ -127,10 +130,11 @@
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtMesasLivresDash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="08"
|
||||
android:text="00"
|
||||
android:textColor="#000"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold" />
|
||||
@@ -161,10 +165,11 @@
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtListaEsperaDash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="05"
|
||||
android:text="00"
|
||||
android:textColor="#000"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
@@ -91,6 +91,16 @@
|
||||
android:textAllCaps="false"
|
||||
android:textColor="#FFFFFF" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnEliminarStaff"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:text="Eliminar Funcionário"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="#FF5252" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtMensagemStaff"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
Reference in New Issue
Block a user