Compare commits
8 Commits
995d23ac7a
...
teste
| Author | SHA1 | Date | |
|---|---|---|---|
| f4d2889718 | |||
| fedcf44c49 | |||
| b2bb591bb7 | |||
| 585af79ffa | |||
| 9d57ed4d0a | |||
| 824ff28001 | |||
| 86dbe2d319 | |||
| 8c1e01dc4c |
4
.idea/deploymentTargetSelector.xml
generated
4
.idea/deploymentTargetSelector.xml
generated
@@ -4,10 +4,10 @@
|
|||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
<DropdownSelection timestamp="2026-04-14T16:06:26.670067Z">
|
<DropdownSelection timestamp="2026-06-30T16:03:11.250011Z">
|
||||||
<Target type="DEFAULT_BOOT">
|
<Target type="DEFAULT_BOOT">
|
||||||
<handle>
|
<handle>
|
||||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=b93659d0e5dd" />
|
<DeviceId pluginId="LocalEmulator" identifier="path=/Users/230409/.android/avd/Pixel_8_Pro.avd" />
|
||||||
</handle>
|
</handle>
|
||||||
</Target>
|
</Target>
|
||||||
</DropdownSelection>
|
</DropdownSelection>
|
||||||
|
|||||||
BIN
OperatingHoursDay.class
Normal file
BIN
OperatingHoursDay.class
Normal file
Binary file not shown.
BIN
TestFirebase.class
Normal file
BIN
TestFirebase.class
Normal file
Binary file not shown.
17
TestFirebase.java
Normal file
17
TestFirebase.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import java.beans.Introspector;
|
||||||
|
import java.beans.PropertyDescriptor;
|
||||||
|
|
||||||
|
public class TestFirebase {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
PropertyDescriptor[] pds = Introspector.getBeanInfo(OperatingHoursDay.class).getPropertyDescriptors();
|
||||||
|
for (PropertyDescriptor pd : pds) {
|
||||||
|
System.out.println("Property: " + pd.getName() + ", readMethod: " + (pd.getReadMethod() != null ? pd.getReadMethod().getName() : "null"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OperatingHoursDay {
|
||||||
|
private boolean isOpen;
|
||||||
|
public boolean getIsOpen() { return isOpen; }
|
||||||
|
public void setIsOpen(boolean isOpen) { this.isOpen = isOpen; }
|
||||||
|
}
|
||||||
@@ -31,6 +31,15 @@ import com.google.firebase.storage.StorageReference;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.app.TimePickerDialog;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import com.example.pap_teste.models.ScheduleDay;
|
||||||
|
|
||||||
public class DefinicoesAdminActivity extends AppCompatActivity {
|
public class DefinicoesAdminActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@@ -42,6 +51,9 @@ public class DefinicoesAdminActivity extends AppCompatActivity {
|
|||||||
private String photoUrl;
|
private String photoUrl;
|
||||||
private ActivityResultLauncher<Intent> imagePickerLauncher;
|
private ActivityResultLauncher<Intent> imagePickerLauncher;
|
||||||
private String[] categories = {"Carnes", "Massas", "Sushi", "Pizzas", "Sobremesas", "Italiana", "Moderna"};
|
private String[] categories = {"Carnes", "Massas", "Sushi", "Pizzas", "Sobremesas", "Italiana", "Moderna"};
|
||||||
|
private String[] dayNames = {"Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"};
|
||||||
|
private String[] dayKeys = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};
|
||||||
|
private List<View> scheduleViews = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -105,6 +117,29 @@ public class DefinicoesAdminActivity extends AppCompatActivity {
|
|||||||
}).show();
|
}).show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
LinearLayout containerSchedule = findViewById(R.id.containerSchedule);
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(this);
|
||||||
|
for (int i = 0; i < dayNames.length; i++) {
|
||||||
|
View view = inflater.inflate(R.layout.item_schedule_day, containerSchedule, false);
|
||||||
|
TextView tvDayName = view.findViewById(R.id.tvDayName);
|
||||||
|
TextView tvOpenTime = view.findViewById(R.id.tvOpenTime);
|
||||||
|
TextView tvCloseTime = view.findViewById(R.id.tvCloseTime);
|
||||||
|
CheckBox cbClosed = view.findViewById(R.id.cbClosed);
|
||||||
|
|
||||||
|
tvDayName.setText(dayNames[i]);
|
||||||
|
|
||||||
|
tvOpenTime.setOnClickListener(v -> showTimePicker(tvOpenTime));
|
||||||
|
tvCloseTime.setOnClickListener(v -> showTimePicker(tvCloseTime));
|
||||||
|
|
||||||
|
cbClosed.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
tvOpenTime.setEnabled(!isChecked);
|
||||||
|
tvCloseTime.setEnabled(!isChecked);
|
||||||
|
});
|
||||||
|
|
||||||
|
containerSchedule.addView(view);
|
||||||
|
scheduleViews.add(view);
|
||||||
|
}
|
||||||
|
|
||||||
loadCurrentSettings();
|
loadCurrentSettings();
|
||||||
|
|
||||||
btnSave.setOnClickListener(v -> saveSettings());
|
btnSave.setOnClickListener(v -> saveSettings());
|
||||||
@@ -130,6 +165,13 @@ public class DefinicoesAdminActivity extends AppCompatActivity {
|
|||||||
builder.show();
|
builder.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showTimePicker(TextView targetTextView) {
|
||||||
|
java.util.Calendar cal = java.util.Calendar.getInstance();
|
||||||
|
new TimePickerDialog(this, (view, hourOfDay, minute) -> {
|
||||||
|
targetTextView.setText(String.format(java.util.Locale.getDefault(), "%02d:%02d", hourOfDay, minute));
|
||||||
|
}, cal.get(java.util.Calendar.HOUR_OF_DAY), cal.get(java.util.Calendar.MINUTE), true).show();
|
||||||
|
}
|
||||||
|
|
||||||
private void uploadImageToFirebase(Uri imageUri) {
|
private void uploadImageToFirebase(Uri imageUri) {
|
||||||
if (documentId == null) return;
|
if (documentId == null) return;
|
||||||
|
|
||||||
@@ -179,6 +221,27 @@ public class DefinicoesAdminActivity extends AppCompatActivity {
|
|||||||
Glide.with(DefinicoesAdminActivity.this).load(photoUrl).circleCrop().into(imgLogo);
|
Glide.with(DefinicoesAdminActivity.this).load(photoUrl).circleCrop().into(imgLogo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (snapshot.hasChild("schedule")) {
|
||||||
|
for (int i = 0; i < dayKeys.length; i++) {
|
||||||
|
DataSnapshot daySnapshot = snapshot.child("schedule").child(dayKeys[i]);
|
||||||
|
if (daySnapshot.exists()) {
|
||||||
|
ScheduleDay sd = daySnapshot.getValue(ScheduleDay.class);
|
||||||
|
if (sd != null) {
|
||||||
|
View view = scheduleViews.get(i);
|
||||||
|
CheckBox cbClosed = view.findViewById(R.id.cbClosed);
|
||||||
|
TextView tvOpenTime = view.findViewById(R.id.tvOpenTime);
|
||||||
|
TextView tvCloseTime = view.findViewById(R.id.tvCloseTime);
|
||||||
|
|
||||||
|
cbClosed.setChecked(sd.isClosed());
|
||||||
|
if (sd.getOpenTime() != null) tvOpenTime.setText(sd.getOpenTime());
|
||||||
|
if (sd.getCloseTime() != null) tvCloseTime.setText(sd.getCloseTime());
|
||||||
|
|
||||||
|
tvOpenTime.setEnabled(!sd.isClosed());
|
||||||
|
tvCloseTime.setEnabled(!sd.isClosed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,6 +276,17 @@ public class DefinicoesAdminActivity extends AppCompatActivity {
|
|||||||
updates.put("logoUrl", photoUrl);
|
updates.put("logoUrl", photoUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, ScheduleDay> scheduleMap = new HashMap<>();
|
||||||
|
for (int i = 0; i < dayKeys.length; i++) {
|
||||||
|
View view = scheduleViews.get(i);
|
||||||
|
CheckBox cbClosed = view.findViewById(R.id.cbClosed);
|
||||||
|
TextView tvOpenTime = view.findViewById(R.id.tvOpenTime);
|
||||||
|
TextView tvCloseTime = view.findViewById(R.id.tvCloseTime);
|
||||||
|
|
||||||
|
scheduleMap.put(dayKeys[i], new ScheduleDay(cbClosed.isChecked(), tvOpenTime.getText().toString(), tvCloseTime.getText().toString()));
|
||||||
|
}
|
||||||
|
updates.put("schedule", scheduleMap);
|
||||||
|
|
||||||
databaseReference.child(documentId).updateChildren(updates)
|
databaseReference.child(documentId).updateChildren(updates)
|
||||||
.addOnSuccessListener(aVoid -> {
|
.addOnSuccessListener(aVoid -> {
|
||||||
Toast.makeText(this, "Definições guardadas com sucesso!", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "Definições guardadas com sucesso!", Toast.LENGTH_SHORT).show();
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ public class EstablishmentDashboardActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
loadProximasReservas();
|
loadProximasReservas();
|
||||||
loadEstatisticas();
|
loadEstatisticas();
|
||||||
|
checkPendingReservationsOnLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadProximasReservas() {
|
private void loadProximasReservas() {
|
||||||
@@ -231,20 +232,93 @@ public class EstablishmentDashboardActivity extends AppCompatActivity {
|
|||||||
.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
|
.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) {
|
public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) {
|
||||||
|
int totalMesas = 0;
|
||||||
|
int mesasOcupadas = 0;
|
||||||
int mesasLivres = 0;
|
int mesasLivres = 0;
|
||||||
for (com.google.firebase.database.DataSnapshot ds : snapshot.getChildren()) {
|
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);
|
com.example.pap_teste.models.Mesa mesa = ds.getValue(com.example.pap_teste.models.Mesa.class);
|
||||||
if (mesa != null && mesa.getRestauranteEmail() != null && mesa.getRestauranteEmail().trim().equalsIgnoreCase(finalEmail)) {
|
if (mesa != null && (mesa.getRestauranteEmail() == null || mesa.getRestauranteEmail().trim().equalsIgnoreCase(finalEmail))) {
|
||||||
if ("Livre".equalsIgnoreCase(mesa.getEstado())) {
|
totalMesas++;
|
||||||
|
if ("Ocupada".equalsIgnoreCase(mesa.getEstado()) || "Reservada".equalsIgnoreCase(mesa.getEstado())) {
|
||||||
|
mesasOcupadas++;
|
||||||
|
} else if ("Livre".equalsIgnoreCase(mesa.getEstado())) {
|
||||||
mesasLivres++;
|
mesasLivres++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (txtMesasLivres != null) txtMesasLivres.setText(String.format(java.util.Locale.US, "%02d", mesasLivres));
|
if (txtMesasLivres != null) txtMesasLivres.setText(mesasOcupadas + " / " + totalMesas);
|
||||||
|
TextView txtMesasLivresSub = findViewById(R.id.txtMesasLivresSub);
|
||||||
|
if (txtMesasLivresSub != null) txtMesasLivresSub.setText(mesasLivres + " livres");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {
|
public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkPendingReservationsOnLogin() {
|
||||||
|
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 != null ? email.trim() : "";
|
||||||
|
|
||||||
|
com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reservas")
|
||||||
|
.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) {
|
||||||
|
java.util.List<com.example.pap_teste.models.Reserva> pendingReservations = new java.util.ArrayList<>();
|
||||||
|
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.getRestauranteEmail() != null && r.getRestauranteEmail().trim().equalsIgnoreCase(finalEmail)) {
|
||||||
|
if ("Pendente".equals(r.getEstado())) {
|
||||||
|
pendingReservations.add(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pendingReservations.isEmpty()) {
|
||||||
|
showPendingReservationsDialog(pendingReservations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showPendingReservationsDialog(java.util.List<com.example.pap_teste.models.Reserva> pendingReservations) {
|
||||||
|
if (isFinishing() || isDestroyed()) return;
|
||||||
|
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this);
|
||||||
|
builder.setTitle("Reservas Pendentes (" + pendingReservations.size() + ")");
|
||||||
|
|
||||||
|
StringBuilder message = new StringBuilder("Tem reservas a aguardar confirmação:\n\n");
|
||||||
|
for (com.example.pap_teste.models.Reserva r : pendingReservations) {
|
||||||
|
message.append("• ").append(r.getData()).append(" às ").append(r.getHora())
|
||||||
|
.append(" - ").append(r.getPessoas()).append(" pessoas")
|
||||||
|
.append("\n Cliente: ").append(r.getClienteEmail()).append("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.setMessage(message.toString());
|
||||||
|
builder.setPositiveButton("Ver Reservas", (dialog, which) -> {
|
||||||
|
Intent intent = new Intent(EstablishmentDashboardActivity.this, DetalhesReservasActivity.class);
|
||||||
|
intent.putExtra(MainActivity.EXTRA_EMAIL, getIntent().getStringExtra(MainActivity.EXTRA_EMAIL));
|
||||||
|
startActivity(intent);
|
||||||
|
});
|
||||||
|
builder.setNegativeButton("Fechar", (dialog, which) -> dialog.dismiss());
|
||||||
|
|
||||||
|
android.app.AlertDialog dialog = builder.create();
|
||||||
|
dialog.show();
|
||||||
|
|
||||||
|
android.widget.TextView textView = dialog.findViewById(android.R.id.message);
|
||||||
|
if (textView != null) {
|
||||||
|
textView.setTextSize(18);
|
||||||
|
textView.setGravity(android.view.Gravity.CENTER);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,13 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
|
|||||||
txtTitle.setText("Reserva: " + (selectedRestaurant != null ? selectedRestaurant.getName() : ""));
|
txtTitle.setText("Reserva: " + (selectedRestaurant != null ? selectedRestaurant.getName() : ""));
|
||||||
setupReservationOptions();
|
setupReservationOptions();
|
||||||
loadRestaurantRating();
|
loadRestaurantRating();
|
||||||
|
|
||||||
|
boolean isFechado = selectedRestaurant != null && selectedRestaurant.isFechadoWebsite();
|
||||||
|
findViewById(R.id.btnSelectDate).setEnabled(!isFechado);
|
||||||
|
findViewById(R.id.btnSelectTime).setEnabled(!isFechado);
|
||||||
|
android.view.View etPartySize = findViewById(R.id.etPartySize);
|
||||||
|
if (etPartySize != null) etPartySize.setEnabled(!isFechado);
|
||||||
|
findViewById(R.id.btnConfirmarReserva).setEnabled(!isFechado);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,8 +167,32 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
|
|||||||
String logoUrl = ds.child("logoUrl").getValue(String.class);
|
String logoUrl = ds.child("logoUrl").getValue(String.class);
|
||||||
|
|
||||||
if (name != null && email != null) {
|
if (name != null && email != null) {
|
||||||
restaurantsList
|
com.example.pap_teste.models.Restaurant rest = new com.example.pap_teste.models.Restaurant(name, cat, email, false, logoUrl);
|
||||||
.add(new com.example.pap_teste.models.Restaurant(name, cat, email, false, logoUrl));
|
Boolean fechadoWebsite = ds.child("fechadoWebsite").getValue(Boolean.class);
|
||||||
|
if (fechadoWebsite != null) rest.setFechadoWebsite(fechadoWebsite);
|
||||||
|
|
||||||
|
if (ds.hasChild("schedule")) {
|
||||||
|
java.util.Map<String, com.example.pap_teste.models.ScheduleDay> schMap = new java.util.HashMap<>();
|
||||||
|
for (com.google.firebase.database.DataSnapshot schDs : ds.child("schedule").getChildren()) {
|
||||||
|
com.example.pap_teste.models.ScheduleDay sd = schDs.getValue(com.example.pap_teste.models.ScheduleDay.class);
|
||||||
|
schMap.put(schDs.getKey(), sd);
|
||||||
|
}
|
||||||
|
rest.setSchedule(schMap);
|
||||||
|
} else if (ds.hasChild("operatingHours")) {
|
||||||
|
java.util.Map<String, com.example.pap_teste.models.ScheduleDay> schMap = new java.util.HashMap<>();
|
||||||
|
for (com.google.firebase.database.DataSnapshot schDs : ds.child("operatingHours").getChildren()) {
|
||||||
|
com.example.pap_teste.models.ScheduleDay sd = schDs.getValue(com.example.pap_teste.models.ScheduleDay.class);
|
||||||
|
if (schDs.hasChild("isOpen")) {
|
||||||
|
Boolean isOpen = schDs.child("isOpen").getValue(Boolean.class);
|
||||||
|
if (isOpen != null && sd != null) {
|
||||||
|
sd.setClosed(!isOpen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
schMap.put(schDs.getKey(), sd);
|
||||||
|
}
|
||||||
|
rest.setSchedule(schMap);
|
||||||
|
}
|
||||||
|
restaurantsList.add(rest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,18 +223,72 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
btnDate.setOnClickListener(v -> {
|
btnDate.setOnClickListener(v -> {
|
||||||
java.util.Calendar cal = java.util.Calendar.getInstance();
|
java.util.Calendar cal = java.util.Calendar.getInstance();
|
||||||
new android.app.DatePickerDialog(this, (view, year, month, dayOfMonth) -> {
|
android.app.DatePickerDialog dpd = new android.app.DatePickerDialog(this, (view, year, month, dayOfMonth) -> {
|
||||||
selectedDate = dayOfMonth + "/" + (month + 1) + "/" + year;
|
java.util.Calendar selectedCal = java.util.Calendar.getInstance();
|
||||||
btnDate.setText(selectedDate);
|
selectedCal.set(year, month, dayOfMonth);
|
||||||
}, cal.get(java.util.Calendar.YEAR), cal.get(java.util.Calendar.MONTH),
|
int dayOfWeek = selectedCal.get(java.util.Calendar.DAY_OF_WEEK);
|
||||||
cal.get(java.util.Calendar.DAY_OF_MONTH)).show();
|
|
||||||
|
boolean isClosed = selectedRestaurant.isClosedForDay(dayOfWeek);
|
||||||
|
|
||||||
|
if (isClosed) {
|
||||||
|
android.widget.Toast.makeText(this, "O restaurante encontra-se encerrado na data selecionada.", android.widget.Toast.LENGTH_LONG).show();
|
||||||
|
selectedDate = null;
|
||||||
|
btnDate.setText("Selecionar Data");
|
||||||
|
btnTime.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
selectedDate = dayOfMonth + "/" + (month + 1) + "/" + year;
|
||||||
|
btnDate.setText(selectedDate);
|
||||||
|
btnTime.setEnabled(true);
|
||||||
|
}
|
||||||
|
}, cal.get(java.util.Calendar.YEAR), cal.get(java.util.Calendar.MONTH), cal.get(java.util.Calendar.DAY_OF_MONTH));
|
||||||
|
dpd.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
|
||||||
|
dpd.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
btnTime.setOnClickListener(v -> {
|
btnTime.setOnClickListener(v -> {
|
||||||
|
if (selectedDate == null) {
|
||||||
|
android.widget.Toast.makeText(this, "Por favor, selecione primeiro a data.", android.widget.Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
java.util.Calendar cal = java.util.Calendar.getInstance();
|
java.util.Calendar cal = java.util.Calendar.getInstance();
|
||||||
new android.app.TimePickerDialog(this, (view, hourOfDay, minute) -> {
|
new android.app.TimePickerDialog(this, (view, hourOfDay, minute) -> {
|
||||||
selectedTime = String.format(java.util.Locale.getDefault(), "%02d:%02d", hourOfDay, minute);
|
String chosenTime = String.format(java.util.Locale.getDefault(), "%02d:%02d", hourOfDay, minute);
|
||||||
btnTime.setText(selectedTime);
|
|
||||||
|
boolean isOutOfHours = false;
|
||||||
|
if (selectedDate != null && selectedRestaurant.getSchedule() != null) {
|
||||||
|
try {
|
||||||
|
java.util.Date d = new java.text.SimpleDateFormat("d/M/yyyy", java.util.Locale.getDefault()).parse(selectedDate);
|
||||||
|
java.util.Calendar selectedCal = java.util.Calendar.getInstance();
|
||||||
|
if (d != null) selectedCal.setTime(d);
|
||||||
|
int dayOfWeek = selectedCal.get(java.util.Calendar.DAY_OF_WEEK);
|
||||||
|
|
||||||
|
com.example.pap_teste.models.ScheduleDay sd = selectedRestaurant.getScheduleForDay(dayOfWeek);
|
||||||
|
if (sd != null && !sd.isClosed()) {
|
||||||
|
if (sd.getOpenTime() != null && sd.getCloseTime() != null && !sd.getOpenTime().isEmpty() && !sd.getCloseTime().isEmpty()) {
|
||||||
|
String open = sd.getOpenTime();
|
||||||
|
String close = sd.getCloseTime();
|
||||||
|
if (open.compareTo(close) < 0) {
|
||||||
|
if (chosenTime.compareTo(open) < 0 || chosenTime.compareTo(close) > 0) {
|
||||||
|
isOutOfHours = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (chosenTime.compareTo(open) < 0 && chosenTime.compareTo(close) > 0) {
|
||||||
|
isOutOfHours = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isOutOfHours) {
|
||||||
|
android.widget.Toast.makeText(this, "Por favor selecione uma hora dentro do horário de funcionamento.", android.widget.Toast.LENGTH_LONG).show();
|
||||||
|
selectedTime = null;
|
||||||
|
btnTime.setText("Selecionar Hora");
|
||||||
|
} else {
|
||||||
|
selectedTime = chosenTime;
|
||||||
|
btnTime.setText(selectedTime);
|
||||||
|
}
|
||||||
}, cal.get(java.util.Calendar.HOUR_OF_DAY), cal.get(java.util.Calendar.MINUTE), true).show();
|
}, cal.get(java.util.Calendar.HOUR_OF_DAY), cal.get(java.util.Calendar.MINUTE), true).show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,18 @@ public class NovaReservaActivity extends AppCompatActivity {
|
|||||||
} else {
|
} else {
|
||||||
txtTitle.setText("Reserva: " + (selectedRestaurant != null ? selectedRestaurant.getName() : ""));
|
txtTitle.setText("Reserva: " + (selectedRestaurant != null ? selectedRestaurant.getName() : ""));
|
||||||
setupReservationOptions();
|
setupReservationOptions();
|
||||||
|
|
||||||
|
android.widget.TextView txtFechado = findViewById(R.id.txtRestauranteFechado);
|
||||||
|
boolean isFechado = selectedRestaurant != null && selectedRestaurant.isFechadoWebsite();
|
||||||
|
|
||||||
|
if (txtFechado != null) {
|
||||||
|
txtFechado.setVisibility(isFechado ? android.view.View.VISIBLE : android.view.View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
findViewById(R.id.btnSelectDate).setEnabled(!isFechado);
|
||||||
|
findViewById(R.id.btnSelectTime).setEnabled(!isFechado);
|
||||||
|
findViewById(R.id.etPartySize).setEnabled(!isFechado);
|
||||||
|
findViewById(R.id.btnConfirmarReserva).setEnabled(!isFechado);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,10 +139,44 @@ public class NovaReservaActivity extends AppCompatActivity {
|
|||||||
String email = ds.child("email").getValue(String.class);
|
String email = ds.child("email").getValue(String.class);
|
||||||
String cat = ds.child("category").getValue(String.class);
|
String cat = ds.child("category").getValue(String.class);
|
||||||
String logoUrl = ds.child("logoUrl").getValue(String.class);
|
String logoUrl = ds.child("logoUrl").getValue(String.class);
|
||||||
|
Boolean fechadoWebsite = ds.child("fechadoWebsite").getValue(Boolean.class);
|
||||||
|
|
||||||
if (name != null && email != null) {
|
if (name != null && email != null) {
|
||||||
filteredList.add(new com.example.pap_teste.models.Restaurant(name, cat, email,
|
com.example.pap_teste.models.Restaurant rest = new com.example.pap_teste.models.Restaurant(name, cat, email,
|
||||||
false, logoUrl));
|
false, logoUrl);
|
||||||
|
if (fechadoWebsite != null) {
|
||||||
|
rest.setFechadoWebsite(fechadoWebsite);
|
||||||
|
}
|
||||||
|
if (ds.hasChild("schedule")) {
|
||||||
|
java.util.Map<String, com.example.pap_teste.models.ScheduleDay> schMap = new java.util.HashMap<>();
|
||||||
|
for (com.google.firebase.database.DataSnapshot schDs : ds.child("schedule").getChildren()) {
|
||||||
|
com.example.pap_teste.models.ScheduleDay sd = schDs.getValue(com.example.pap_teste.models.ScheduleDay.class);
|
||||||
|
schMap.put(schDs.getKey(), sd);
|
||||||
|
}
|
||||||
|
rest.setSchedule(schMap);
|
||||||
|
} else if (ds.hasChild("operatingHours")) {
|
||||||
|
java.util.Map<String, com.example.pap_teste.models.ScheduleDay> schMap = new java.util.HashMap<>();
|
||||||
|
for (com.google.firebase.database.DataSnapshot schDs : ds.child("operatingHours").getChildren()) {
|
||||||
|
com.example.pap_teste.models.ScheduleDay sd = schDs.getValue(com.example.pap_teste.models.ScheduleDay.class);
|
||||||
|
// Handle case where operatingHours has isOpen instead of closed
|
||||||
|
if (schDs.hasChild("isOpen")) {
|
||||||
|
Boolean isOpen = schDs.child("isOpen").getValue(Boolean.class);
|
||||||
|
if (isOpen != null && sd != null) {
|
||||||
|
sd.setClosed(!isOpen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
schMap.put(schDs.getKey(), sd);
|
||||||
|
}
|
||||||
|
rest.setSchedule(schMap);
|
||||||
|
} else if (ds.hasChild("horario")) {
|
||||||
|
java.util.Map<String, com.example.pap_teste.models.ScheduleDay> schMap = new java.util.HashMap<>();
|
||||||
|
for (com.google.firebase.database.DataSnapshot schDs : ds.child("horario").getChildren()) {
|
||||||
|
com.example.pap_teste.models.ScheduleDay sd = schDs.getValue(com.example.pap_teste.models.ScheduleDay.class);
|
||||||
|
schMap.put(schDs.getKey(), sd);
|
||||||
|
}
|
||||||
|
rest.setSchedule(schMap);
|
||||||
|
}
|
||||||
|
filteredList.add(rest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,18 +210,72 @@ public class NovaReservaActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
btnDate.setOnClickListener(v -> {
|
btnDate.setOnClickListener(v -> {
|
||||||
java.util.Calendar cal = java.util.Calendar.getInstance();
|
java.util.Calendar cal = java.util.Calendar.getInstance();
|
||||||
new android.app.DatePickerDialog(this, (view, year, month, dayOfMonth) -> {
|
android.app.DatePickerDialog dpd = new android.app.DatePickerDialog(this, (view, year, month, dayOfMonth) -> {
|
||||||
selectedDate = dayOfMonth + "/" + (month + 1) + "/" + year;
|
java.util.Calendar selectedCal = java.util.Calendar.getInstance();
|
||||||
btnDate.setText(selectedDate);
|
selectedCal.set(year, month, dayOfMonth);
|
||||||
}, cal.get(java.util.Calendar.YEAR), cal.get(java.util.Calendar.MONTH),
|
int dayOfWeek = selectedCal.get(java.util.Calendar.DAY_OF_WEEK);
|
||||||
cal.get(java.util.Calendar.DAY_OF_MONTH)).show();
|
|
||||||
|
boolean isClosed = selectedRestaurant.isClosedForDay(dayOfWeek);
|
||||||
|
|
||||||
|
if (isClosed) {
|
||||||
|
android.widget.Toast.makeText(this, "O restaurante encontra-se encerrado na data selecionada.", android.widget.Toast.LENGTH_LONG).show();
|
||||||
|
selectedDate = null;
|
||||||
|
btnDate.setText("Selecionar Data");
|
||||||
|
btnTime.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
selectedDate = dayOfMonth + "/" + (month + 1) + "/" + year;
|
||||||
|
btnDate.setText(selectedDate);
|
||||||
|
btnTime.setEnabled(true);
|
||||||
|
}
|
||||||
|
}, cal.get(java.util.Calendar.YEAR), cal.get(java.util.Calendar.MONTH), cal.get(java.util.Calendar.DAY_OF_MONTH));
|
||||||
|
dpd.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
|
||||||
|
dpd.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
btnTime.setOnClickListener(v -> {
|
btnTime.setOnClickListener(v -> {
|
||||||
|
if (selectedDate == null) {
|
||||||
|
android.widget.Toast.makeText(this, "Por favor, selecione primeiro a data.", android.widget.Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
java.util.Calendar cal = java.util.Calendar.getInstance();
|
java.util.Calendar cal = java.util.Calendar.getInstance();
|
||||||
new android.app.TimePickerDialog(this, (view, hourOfDay, minute) -> {
|
new android.app.TimePickerDialog(this, (view, hourOfDay, minute) -> {
|
||||||
selectedTime = String.format(java.util.Locale.getDefault(), "%02d:%02d", hourOfDay, minute);
|
String chosenTime = String.format(java.util.Locale.getDefault(), "%02d:%02d", hourOfDay, minute);
|
||||||
btnTime.setText(selectedTime);
|
|
||||||
|
boolean isOutOfHours = false;
|
||||||
|
if (selectedDate != null && selectedRestaurant.getSchedule() != null) {
|
||||||
|
try {
|
||||||
|
java.util.Date d = new java.text.SimpleDateFormat("d/M/yyyy", java.util.Locale.getDefault()).parse(selectedDate);
|
||||||
|
java.util.Calendar selectedCal = java.util.Calendar.getInstance();
|
||||||
|
if (d != null) selectedCal.setTime(d);
|
||||||
|
int dayOfWeek = selectedCal.get(java.util.Calendar.DAY_OF_WEEK);
|
||||||
|
|
||||||
|
com.example.pap_teste.models.ScheduleDay sd = selectedRestaurant.getScheduleForDay(dayOfWeek);
|
||||||
|
if (sd != null && !sd.isClosed()) {
|
||||||
|
if (sd.getOpenTime() != null && sd.getCloseTime() != null && !sd.getOpenTime().isEmpty() && !sd.getCloseTime().isEmpty()) {
|
||||||
|
String open = sd.getOpenTime();
|
||||||
|
String close = sd.getCloseTime();
|
||||||
|
if (open.compareTo(close) < 0) {
|
||||||
|
if (chosenTime.compareTo(open) < 0 || chosenTime.compareTo(close) > 0) {
|
||||||
|
isOutOfHours = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (chosenTime.compareTo(open) < 0 && chosenTime.compareTo(close) > 0) {
|
||||||
|
isOutOfHours = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isOutOfHours) {
|
||||||
|
android.widget.Toast.makeText(this, "Por favor selecione uma hora dentro do horário de funcionamento.", android.widget.Toast.LENGTH_LONG).show();
|
||||||
|
selectedTime = null;
|
||||||
|
btnTime.setText("Selecionar Hora");
|
||||||
|
} else {
|
||||||
|
selectedTime = chosenTime;
|
||||||
|
btnTime.setText(selectedTime);
|
||||||
|
}
|
||||||
}, cal.get(java.util.Calendar.HOUR_OF_DAY), cal.get(java.util.Calendar.MINUTE), true).show();
|
}, cal.get(java.util.Calendar.HOUR_OF_DAY), cal.get(java.util.Calendar.MINUTE), true).show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ public class ProfileDashboardActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private void performLogOut() {
|
private void performLogOut() {
|
||||||
try {
|
try {
|
||||||
|
stopService(new Intent(this, ReservationNotificationService.class));
|
||||||
FirebaseAuth.getInstance().signOut();
|
FirebaseAuth.getInstance().signOut();
|
||||||
Toast.makeText(this, "Sessão terminada com sucesso.", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "Sessão terminada com sucesso.", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.example.pap_teste.models;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import com.google.firebase.database.PropertyName;
|
||||||
|
|
||||||
|
public class OperatingHoursDay implements Serializable {
|
||||||
|
@PropertyName("isOpen")
|
||||||
|
private boolean openStatus;
|
||||||
|
private String openTime;
|
||||||
|
private String closeTime;
|
||||||
|
|
||||||
|
public OperatingHoursDay() {
|
||||||
|
// Construtor vazio necessário para Firebase
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("isOpen")
|
||||||
|
public boolean getOpenStatus() {
|
||||||
|
return openStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("isOpen")
|
||||||
|
public void setOpenStatus(boolean openStatus) {
|
||||||
|
this.openStatus = openStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOpenTime() {
|
||||||
|
return openTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOpenTime(String openTime) {
|
||||||
|
this.openTime = openTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCloseTime() {
|
||||||
|
return closeTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCloseTime(String closeTime) {
|
||||||
|
this.closeTime = closeTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ public class Restaurant implements Serializable {
|
|||||||
private String logoUrl;
|
private String logoUrl;
|
||||||
private Double ratingAvg;
|
private Double ratingAvg;
|
||||||
private Integer ratingCount;
|
private Integer ratingCount;
|
||||||
|
private boolean fechadoWebsite;
|
||||||
|
|
||||||
// No-argument constructor required for Firebase
|
// No-argument constructor required for Firebase
|
||||||
public Restaurant() {
|
public Restaurant() {
|
||||||
@@ -41,9 +42,51 @@ public class Restaurant implements Serializable {
|
|||||||
public void setEmail(String email) { this.email = email; }
|
public void setEmail(String email) { this.email = email; }
|
||||||
public void setAvailable(boolean available) { this.available = available; }
|
public void setAvailable(boolean available) { this.available = available; }
|
||||||
public void setLogoUrl(String logoUrl) { this.logoUrl = logoUrl; }
|
public void setLogoUrl(String logoUrl) { this.logoUrl = logoUrl; }
|
||||||
|
public boolean isFechadoWebsite() { return fechadoWebsite; }
|
||||||
|
public void setFechadoWebsite(boolean fechadoWebsite) { this.fechadoWebsite = fechadoWebsite; }
|
||||||
|
|
||||||
public Double getRatingAvg() { return ratingAvg; }
|
public Double getRatingAvg() { return ratingAvg; }
|
||||||
public void setRatingAvg(Double ratingAvg) { this.ratingAvg = ratingAvg; }
|
public void setRatingAvg(Double ratingAvg) { this.ratingAvg = ratingAvg; }
|
||||||
public Integer getRatingCount() { return ratingCount; }
|
public Integer getRatingCount() { return ratingCount; }
|
||||||
public void setRatingCount(Integer ratingCount) { this.ratingCount = ratingCount; }
|
public void setRatingCount(Integer ratingCount) { this.ratingCount = ratingCount; }
|
||||||
|
|
||||||
|
private java.util.Map<String, ScheduleDay> schedule;
|
||||||
|
public java.util.Map<String, ScheduleDay> getSchedule() { return schedule; }
|
||||||
|
public void setSchedule(java.util.Map<String, ScheduleDay> schedule) { this.schedule = schedule; }
|
||||||
|
|
||||||
|
public ScheduleDay getScheduleForDay(int dayOfWeekCalendar) {
|
||||||
|
if (schedule == null) return null;
|
||||||
|
String[] dayKeys = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};
|
||||||
|
String[] dayKeysPt = {"domingo", "segunda-feira", "terça-feira", "quarta-feira", "quinta-feira", "sexta-feira", "sábado"};
|
||||||
|
String[] dayKeysPtShort = {"domingo", "segunda", "terça", "quarta", "quinta", "sexta", "sábado"};
|
||||||
|
int index = dayOfWeekCalendar - 1;
|
||||||
|
|
||||||
|
ScheduleDay sd = schedule.get(dayKeys[index]);
|
||||||
|
if (sd == null) sd = schedule.get(dayKeysPt[index]);
|
||||||
|
if (sd == null) sd = schedule.get(dayKeysPtShort[index]);
|
||||||
|
if (sd == null) sd = schedule.get(String.valueOf(index));
|
||||||
|
|
||||||
|
if (sd == null) {
|
||||||
|
for (java.util.Map.Entry<String, ScheduleDay> entry : schedule.entrySet()) {
|
||||||
|
String k = entry.getKey().toLowerCase(java.util.Locale.ROOT).replace("-", "").replace(" ", "");
|
||||||
|
String expected1 = dayKeys[index].replace("-", "");
|
||||||
|
String expected2 = dayKeysPt[index].replace("-", "");
|
||||||
|
String expected3 = dayKeysPtShort[index].replace("-", "");
|
||||||
|
|
||||||
|
if (k.equals(expected1) || k.equals(expected2) || k.equals(expected3) || k.equals(String.valueOf(index))) {
|
||||||
|
return entry.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isClosedForDay(int dayOfWeekCalendar) {
|
||||||
|
if (schedule == null || schedule.isEmpty()) return false; // If no schedule is set at all, default to open to avoid locking out old restaurants.
|
||||||
|
ScheduleDay sd = getScheduleForDay(dayOfWeekCalendar);
|
||||||
|
if (sd == null) {
|
||||||
|
return true; // Se o dia não existe no mapa de um restaurante com horário, está fechado.
|
||||||
|
}
|
||||||
|
return sd.isClosed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package com.example.pap_teste.models;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class ScheduleDay implements Serializable {
|
||||||
|
private boolean closed;
|
||||||
|
private Boolean isOpen;
|
||||||
|
private String openTime;
|
||||||
|
private String closeTime;
|
||||||
|
|
||||||
|
public ScheduleDay() {
|
||||||
|
// No-argument constructor for Firebase
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScheduleDay(boolean closed, String openTime, String closeTime) {
|
||||||
|
this.closed = closed;
|
||||||
|
this.isOpen = !closed;
|
||||||
|
this.openTime = openTime;
|
||||||
|
this.closeTime = closeTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isClosed() {
|
||||||
|
if (isOpen != null) {
|
||||||
|
return !isOpen;
|
||||||
|
}
|
||||||
|
return closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClosed(boolean closed) {
|
||||||
|
this.closed = closed;
|
||||||
|
if (this.isOpen == null) {
|
||||||
|
this.isOpen = !closed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles potential "isClosed" boolean in Firebase
|
||||||
|
public void setIsClosed(Boolean isClosed) {
|
||||||
|
if (isClosed != null) {
|
||||||
|
this.closed = isClosed;
|
||||||
|
this.isOpen = !isClosed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles potential "fechado" boolean from Portuguese web dashboards
|
||||||
|
public void setFechado(Boolean fechado) {
|
||||||
|
if (fechado != null) {
|
||||||
|
this.closed = fechado;
|
||||||
|
this.isOpen = !fechado;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@com.google.firebase.database.PropertyName("isOpen")
|
||||||
|
public Boolean getIsOpen() {
|
||||||
|
return isOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@com.google.firebase.database.PropertyName("isOpen")
|
||||||
|
public void setIsOpen(Boolean isOpen) {
|
||||||
|
this.isOpen = isOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOpenTime() {
|
||||||
|
return openTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOpenTime(String openTime) {
|
||||||
|
this.openTime = openTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCloseTime() {
|
||||||
|
return closeTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCloseTime(String closeTime) {
|
||||||
|
this.closeTime = closeTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
app/src/main/res/drawable/ic_clock_gold.xml
Normal file
13
app/src/main/res/drawable/ic_clock_gold.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#D4AF37">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12.5,7H11v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z" />
|
||||||
|
</vector>
|
||||||
@@ -156,6 +156,22 @@
|
|||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:background="@drawable/input_bg" />
|
android:background="@drawable/input_bg" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="Horário de Funcionamento"
|
||||||
|
android:textColor="@color/colorTextPrimary"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:fontFamily="sans-serif-medium" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/containerSchedule"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:orientation="vertical" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/btnSaveSettings"
|
android:id="@+id/btnSaveSettings"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -71,116 +71,150 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="32dp"
|
android:layout_marginTop="32dp"
|
||||||
android:orientation="horizontal">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<!-- MESAS OCUPADAS CARD -->
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/cardReservasHoje"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="6dp"
|
app:cardBackgroundColor="#1F1D1A"
|
||||||
android:layout_weight="1"
|
|
||||||
android:foreground="?attr/selectableItemBackground"
|
|
||||||
app:cardBackgroundColor="@color/colorSurface"
|
|
||||||
app:cardCornerRadius="16dp"
|
app:cardCornerRadius="16dp"
|
||||||
app:cardElevation="2dp">
|
app:cardElevation="2dp">
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:padding="20dp">
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/lblMesasOcupadas"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Reservas"
|
android:text="MESAS OCUPADAS"
|
||||||
android:textColor="@color/colorTextSecondary"
|
android:textColor="#888175"
|
||||||
android:textSize="13sp" />
|
android:textSize="14sp"
|
||||||
|
android:letterSpacing="0.05"
|
||||||
|
android:fontFamily="serif"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<TextView
|
<ImageView
|
||||||
android:id="@+id/txtReservasHojeDash"
|
android:layout_width="24dp"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="24dp"
|
||||||
android:layout_height="wrap_content"
|
android:src="@drawable/ic_clock_gold"
|
||||||
android:layout_marginTop="6dp"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:text="00"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
android:textColor="@color/colorPrimary"
|
app:layout_constraintBottom_toBottomOf="@id/lblMesasOcupadas" />
|
||||||
android:textSize="30sp"
|
|
||||||
android:fontFamily="sans-serif-medium" />
|
|
||||||
</LinearLayout>
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="6dp"
|
|
||||||
android:layout_marginEnd="6dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
app:cardBackgroundColor="@color/colorSurface"
|
|
||||||
app:cardCornerRadius="16dp"
|
|
||||||
app:cardElevation="2dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Mesas"
|
|
||||||
android:textColor="@color/colorTextSecondary"
|
|
||||||
android:textSize="13sp" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/txtMesasLivresDash"
|
android:id="@+id/txtMesasLivresDash"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="6dp"
|
android:layout_marginTop="16dp"
|
||||||
android:text="00"
|
android:text="0 / 0"
|
||||||
android:textColor="@color/colorTextPrimary"
|
android:textColor="#FFFFFF"
|
||||||
android:textSize="30sp"
|
android:textSize="38sp"
|
||||||
android:fontFamily="sans-serif-medium" />
|
android:fontFamily="serif-monospace"
|
||||||
</LinearLayout>
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/lblMesasOcupadas" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtMesasLivresSub"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="0 livres"
|
||||||
|
android:textColor="#D4AF37"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:fontFamily="sans-serif-medium"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/txtMesasLivresDash" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="6dp"
|
android:layout_marginTop="12dp"
|
||||||
android:layout_weight="1"
|
android:orientation="horizontal">
|
||||||
app:cardBackgroundColor="@color/colorSurface"
|
|
||||||
app:cardCornerRadius="16dp"
|
|
||||||
app:cardElevation="2dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
<!-- RESERVAS CARD -->
|
||||||
android:layout_width="match_parent"
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/cardReservasHoje"
|
||||||
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:layout_marginEnd="6dp"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:padding="16dp">
|
android:foreground="?attr/selectableItemBackground"
|
||||||
|
app:cardBackgroundColor="@color/colorSurface"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Espera"
|
android:gravity="center"
|
||||||
android:textColor="@color/colorTextSecondary"
|
android:orientation="vertical"
|
||||||
android:textSize="13sp" />
|
android:padding="16dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/txtListaEsperaDash"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Reservas"
|
||||||
|
android:textColor="@color/colorTextSecondary"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtReservasHojeDash"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
|
android:text="00"
|
||||||
|
android:textColor="@color/colorPrimary"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:fontFamily="sans-serif-medium" />
|
||||||
|
</LinearLayout>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<!-- ESPERA CARD -->
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="6dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
app:cardBackgroundColor="@color/colorSurface"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="6dp"
|
android:gravity="center"
|
||||||
android:text="00"
|
android:orientation="vertical"
|
||||||
android:textColor="@color/colorWarning"
|
android:padding="16dp">
|
||||||
android:textSize="30sp"
|
|
||||||
android:fontFamily="sans-serif-medium" />
|
|
||||||
</LinearLayout>
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Espera"
|
||||||
|
android:textColor="@color/colorTextSecondary"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtListaEsperaDash"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
|
android:text="00"
|
||||||
|
android:textColor="@color/colorWarning"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:fontFamily="sans-serif-medium" />
|
||||||
|
</LinearLayout>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@@ -122,6 +122,19 @@
|
|||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:layout_marginBottom="24dp" />
|
android:layout_marginBottom="24dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtRestauranteFechado"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Restaurante fechado temporariamente. Não é possível efetuar reservas."
|
||||||
|
android:textColor="@android:color/holo_red_dark"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="8dp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|||||||
52
app/src/main/res/layout/item_schedule_day.xml
Normal file
52
app/src/main/res/layout/item_schedule_day.xml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingVertical="8dp">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/cbClosed"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Folga"
|
||||||
|
android:textColor="@color/colorTextSecondary" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvDayName"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:text="Segunda-feira"
|
||||||
|
android:textColor="@color/colorTextPrimary"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:fontFamily="sans-serif-medium" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvOpenTime"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="09:00"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:background="@drawable/input_bg"
|
||||||
|
android:textColor="@color/colorTextPrimary" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="-"
|
||||||
|
android:layout_marginHorizontal="8dp"
|
||||||
|
android:textColor="@color/colorTextSecondary" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvCloseTime"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="22:00"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:background="@drawable/input_bg"
|
||||||
|
android:textColor="@color/colorTextPrimary" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "9.1.0"
|
agp = "9.1.1"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
junitVersion = "1.3.0"
|
junitVersion = "1.3.0"
|
||||||
espressoCore = "3.7.0"
|
espressoCore = "3.7.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user