This commit is contained in:
2026-03-18 10:40:19 +00:00
parent 88ef4b6796
commit a921553f2b
14 changed files with 438 additions and 221 deletions

View File

@@ -53,6 +53,7 @@ public class ClientDashboardActivity extends AppCompatActivity {
});
updateGreeting();
fetchProfilePicture();
setupCategories();
setupActions();
}
@@ -61,6 +62,22 @@ public class ClientDashboardActivity extends AppCompatActivity {
txtGreeting.setText(String.format("Olá, %s", displayName != null ? displayName : "convidado"));
}
private void fetchProfilePicture() {
if (email == null) return;
String documentId = email.replace(".", "_").replace("@", "_at_");
com.google.firebase.database.FirebaseDatabase.getInstance().getReference()
.child("users").child(documentId).child("photoUrl")
.get().addOnSuccessListener(snapshot -> {
if (!isDestroyed() && snapshot.exists()) {
String photoUrl = snapshot.getValue(String.class);
if (photoUrl != null && !photoUrl.isEmpty()) {
android.widget.ImageView imgProfile = findViewById(R.id.imgProfile);
com.bumptech.glide.Glide.with(this).load(photoUrl).circleCrop().into(imgProfile);
}
}
});
}
private void setupCategories() {
RecyclerView rv = findViewById(R.id.rvCategories);
List<FoodCategory> cats = new ArrayList<>();
@@ -90,9 +107,14 @@ public class ClientDashboardActivity extends AppCompatActivity {
findViewById(R.id.btnVoltar).setOnClickListener(v -> finish());
findViewById(R.id.btnCheckIn).setOnClickListener(v -> {
Intent intent = new Intent(this, CheckInAntecipadoActivity.class);
intent.putExtra("restaurant_email", "sabor_arte@restaurante.com");
startActivity(intent);
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(

View File

@@ -25,7 +25,7 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
private String selectedDate = null;
private String selectedTime = null;
private int selectedPartySize = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -120,51 +120,37 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
}
});
}
private void setupReservationOptions() {
// Dates
androidx.recyclerview.widget.RecyclerView rvDates = findViewById(R.id.rvDates);
java.util.List<String> dates = new java.util.ArrayList<>();
dates.add("Hoje");
dates.add("Amanhã");
dates.add("Quarta, 12 Mar");
dates.add("Quinta, 13 Mar");
dates.add("Sexta, 14 Mar");
rvDates.setAdapter(new ReservationOptionAdapter(dates, date -> selectedDate = date));
android.widget.Button btnDate = findViewById(R.id.btnSelectDate);
android.widget.Button btnTime = findViewById(R.id.btnSelectTime);
// Times
androidx.recyclerview.widget.RecyclerView rvTimes = findViewById(R.id.rvTimes);
java.util.List<String> times = new java.util.ArrayList<>();
times.add("12:00");
times.add("13:00");
times.add("19:00");
times.add("20:00");
times.add("21:00");
times.add("22:00");
rvTimes.setAdapter(new ReservationOptionAdapter(times, time -> selectedTime = time));
btnDate.setOnClickListener(v -> {
java.util.Calendar cal = java.util.Calendar.getInstance();
new android.app.DatePickerDialog(this, (view, year, month, dayOfMonth) -> {
selectedDate = dayOfMonth + "/" + (month + 1) + "/" + year;
btnDate.setText(selectedDate);
}, cal.get(java.util.Calendar.YEAR), cal.get(java.util.Calendar.MONTH), cal.get(java.util.Calendar.DAY_OF_MONTH)).show();
});
// Party Size
androidx.recyclerview.widget.RecyclerView rvParty = findViewById(R.id.rvPartySize);
java.util.List<String> party = new java.util.ArrayList<>();
party.add("1 pessoa");
party.add("2 pessoas");
party.add("3 pessoas");
party.add("4 pessoas");
party.add("5 pessoas");
party.add("6+ pessoas");
rvParty.setAdapter(new ReservationOptionAdapter(party, size -> {
try {
selectedPartySize = Integer.parseInt(size.split(" ")[0].replace("+", ""));
} catch (Exception e) {
selectedPartySize = 6;
}
}));
btnTime.setOnClickListener(v -> {
java.util.Calendar cal = java.util.Calendar.getInstance();
new android.app.TimePickerDialog(this, (view, hourOfDay, minute) -> {
selectedTime = String.format(java.util.Locale.getDefault(), "%02d:%02d", hourOfDay, minute);
btnTime.setText(selectedTime);
}, cal.get(java.util.Calendar.HOUR_OF_DAY), cal.get(java.util.Calendar.MINUTE), true).show();
});
findViewById(R.id.btnConfirmarReserva).setOnClickListener(v -> saveReservation());
}
private void saveReservation() {
if (selectedDate == null || selectedTime == null || selectedPartySize == 0) {
android.widget.EditText etPartySize = findViewById(R.id.etPartySize);
int partySize = 0;
try {
partySize = Integer.parseInt(etPartySize.getText().toString());
} catch (Exception e) {}
if (selectedDate == null || selectedTime == null || partySize == 0) {
android.widget.Toast.makeText(this, "Por favor, selecione data, hora e número de pessoas.",
android.widget.Toast.LENGTH_SHORT).show();
return;
@@ -185,7 +171,7 @@ public class ExplorarRestaurantesActivity extends AppCompatActivity {
selectedRestaurant.getEmail(),
selectedDate,
selectedTime,
selectedPartySize,
partySize,
"Pendente");
if (id != null) {

View File

@@ -3,15 +3,33 @@ package com.example.pap_teste;
import android.os.Bundle;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import android.widget.Button;
import android.widget.Toast;
import com.example.pap_teste.models.Restaurant;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class FavoritosActivity extends AppCompatActivity {
private androidx.recyclerview.widget.RecyclerView rv;
private RestaurantAdapter adapter;
private List<Restaurant> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -28,16 +46,39 @@ public class FavoritosActivity extends AppCompatActivity {
back.setOnClickListener(v -> finish());
}
rv = findViewById(R.id.rvFavoritos);
list = new ArrayList<>();
adapter = new RestaurantAdapter(list, null);
rv.setAdapter(adapter);
setupFavoritesList();
}
private void setupFavoritesList() {
androidx.recyclerview.widget.RecyclerView rv = findViewById(R.id.rvFavoritos);
java.util.List<com.example.pap_teste.models.Restaurant> list = new java.util.ArrayList<>();
list.add(new com.example.pap_teste.models.Restaurant("Sabor & Arte", "Tradicional", "sabor_arte@restaurante.com", true));
list.add(new com.example.pap_teste.models.Restaurant("O Chuveiro", "Mariscos", "chuveiro@restaurante.com", true));
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null && user.getEmail() != null) {
String encodedUserEmail = user.getEmail().replace(".", "_").replace("@", "_at_");
DatabaseReference favRef = FirebaseDatabase.getInstance().getReference("users")
.child(encodedUserEmail).child("favorites");
RestaurantAdapter adapter = new RestaurantAdapter(list, null);
rv.setAdapter(adapter);
favRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
list.clear();
for (DataSnapshot ds : snapshot.getChildren()) {
Restaurant restaurant = ds.getValue(Restaurant.class);
if (restaurant != null) {
list.add(restaurant);
}
}
adapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
Toast.makeText(FavoritosActivity.this, "Erro ao carregar favoritos.", Toast.LENGTH_SHORT).show();
}
});
}
}
}

View File

@@ -67,6 +67,9 @@ public class MainActivity extends AppCompatActivity {
private EditText inputEstablishmentName;
private EditText inputEstablishmentEmail;
private EditText inputEstablishmentPhone;
private android.widget.TextView txtForgotPassword;
private android.widget.ImageView iconPasswordVisibility;
private boolean isPasswordVisible = false;
private boolean hasCreatedAccount;
private FirebaseAuth firebaseAuth;
private DatabaseReference databaseReference;
@@ -149,6 +152,50 @@ public class MainActivity extends AppCompatActivity {
inputEstablishmentName = findViewById(R.id.inputEstablishmentName);
inputEstablishmentEmail = findViewById(R.id.inputEstablishmentEmail);
inputEstablishmentPhone = findViewById(R.id.inputEstablishmentPhone);
txtForgotPassword = findViewById(R.id.txtForgotPassword);
iconPasswordVisibility = findViewById(R.id.iconPasswordVisibility);
setupPasswordFeatures();
}
private void setupPasswordFeatures() {
iconPasswordVisibility.setOnClickListener(v -> {
isPasswordVisible = !isPasswordVisible;
if (isPasswordVisible) {
inputPassword.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
iconPasswordVisibility.setImageResource(R.drawable.ic_visibility);
} else {
inputPassword.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD);
iconPasswordVisibility.setImageResource(R.drawable.ic_visibility_off);
}
inputPassword.setSelection(inputPassword.getText().length());
});
txtForgotPassword.setOnClickListener(v -> {
String email = inputEmail.getText().toString().trim();
if (TextUtils.isEmpty(email)) {
Toast.makeText(this, "Por favor, introduza o seu email primeiro.", Toast.LENGTH_SHORT).show();
return;
}
new AlertDialog.Builder(this)
.setTitle("Recuperar palavra-passe")
.setMessage("Deseja enviar um email de recuperação para " + email + "?")
.setPositiveButton("Sim", (dialog, which) -> {
if (firebaseAuth != null) {
firebaseAuth.sendPasswordResetEmail(email)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Toast.makeText(MainActivity.this, "Email de recuperação enviado!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this, "Falha ao enviar email. Verifique se o endereço está correto.", Toast.LENGTH_LONG).show();
}
});
}
})
.setNegativeButton("Não", null)
.show();
});
}
private void setupTypeToggle() {
@@ -217,6 +264,10 @@ public class MainActivity extends AppCompatActivity {
inputEstablishmentName.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE);
inputEstablishmentEmail.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE);
inputEstablishmentPhone.setVisibility(creatingAccount && isEstablishment ? View.VISIBLE : View.GONE);
if (txtForgotPassword != null) {
txtForgotPassword.setVisibility(creatingAccount ? View.GONE : View.VISIBLE);
}
}
private void handlePrimaryAction() {

View File

@@ -138,52 +138,38 @@ public class NovaReservaActivity extends AppCompatActivity {
private String selectedDate = null;
private String selectedTime = null;
private int selectedPartySize = 0;
private void setupReservationOptions() {
// Dates
RecyclerView rvDates = findViewById(R.id.rvDates);
java.util.List<String> dates = new java.util.ArrayList<>();
dates.add("Hoje");
dates.add("Amanhã");
dates.add("Quarta, 12 Mar");
dates.add("Quinta, 13 Mar");
dates.add("Sexta, 14 Mar");
rvDates.setAdapter(new ReservationOptionAdapter(dates, date -> selectedDate = date));
android.widget.Button btnDate = findViewById(R.id.btnSelectDate);
android.widget.Button btnTime = findViewById(R.id.btnSelectTime);
// Times
RecyclerView rvTimes = findViewById(R.id.rvTimes);
java.util.List<String> times = new java.util.ArrayList<>();
times.add("12:00");
times.add("13:00");
times.add("19:00");
times.add("20:00");
times.add("21:00");
times.add("22:00");
rvTimes.setAdapter(new ReservationOptionAdapter(times, time -> selectedTime = time));
btnDate.setOnClickListener(v -> {
java.util.Calendar cal = java.util.Calendar.getInstance();
new android.app.DatePickerDialog(this, (view, year, month, dayOfMonth) -> {
selectedDate = dayOfMonth + "/" + (month + 1) + "/" + year;
btnDate.setText(selectedDate);
}, cal.get(java.util.Calendar.YEAR), cal.get(java.util.Calendar.MONTH), cal.get(java.util.Calendar.DAY_OF_MONTH)).show();
});
// Party Size
RecyclerView rvParty = findViewById(R.id.rvPartySize);
java.util.List<String> party = new java.util.ArrayList<>();
party.add("1 pessoa");
party.add("2 pessoas");
party.add("3 pessoas");
party.add("4 pessoas");
party.add("5 pessoas");
party.add("6+ pessoas");
rvParty.setAdapter(new ReservationOptionAdapter(party, size -> {
try {
selectedPartySize = Integer.parseInt(size.split(" ")[0].replace("+", ""));
} catch (Exception e) {
selectedPartySize = 6;
}
}));
btnTime.setOnClickListener(v -> {
java.util.Calendar cal = java.util.Calendar.getInstance();
new android.app.TimePickerDialog(this, (view, hourOfDay, minute) -> {
selectedTime = String.format(java.util.Locale.getDefault(), "%02d:%02d", hourOfDay, minute);
btnTime.setText(selectedTime);
}, cal.get(java.util.Calendar.HOUR_OF_DAY), cal.get(java.util.Calendar.MINUTE), true).show();
});
findViewById(R.id.btnConfirmarReserva).setOnClickListener(v -> saveReservation());
}
private void saveReservation() {
if (selectedDate == null || selectedTime == null || selectedPartySize == 0) {
android.widget.EditText etPartySize = findViewById(R.id.etPartySize);
int partySize = 0;
try {
partySize = Integer.parseInt(etPartySize.getText().toString());
} catch (Exception e) {}
if (selectedDate == null || selectedTime == null || partySize == 0) {
android.widget.Toast.makeText(this, "Por favor, selecione data, hora e número de pessoas.",
android.widget.Toast.LENGTH_SHORT).show();
return;
@@ -203,7 +189,7 @@ public class NovaReservaActivity extends AppCompatActivity {
selectedRestaurant.getEmail(),
selectedDate,
selectedTime,
selectedPartySize,
partySize,
"Pendente");
if (id != null) {

View File

@@ -168,10 +168,21 @@ public class ProfileDashboardActivity extends AppCompatActivity {
storageRef.getDownloadUrl().addOnSuccessListener(uri -> {
photoUrl = uri.toString();
Glide.with(this).load(photoUrl).circleCrop().into(imgProfile);
Toast.makeText(this, "Foto carregada!", Toast.LENGTH_SHORT).show();
// Salvar a nova URL da foto imediatamente na DB
Map<String, Object> photoUpdate = new HashMap<>();
photoUpdate.put("photoUrl", photoUrl);
databaseReference.child(documentId).updateChildren(photoUpdate).addOnCompleteListener(dbTask -> {
if (dbTask.isSuccessful()) {
Toast.makeText(this, "Foto atualizada com sucesso!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Foto enviada, mas não foi possível atualizar o perfil.", Toast.LENGTH_SHORT).show();
}
});
});
}).addOnFailureListener(e -> {
Toast.makeText(this, "Falha no upload.", Toast.LENGTH_SHORT).show();
Toast.makeText(this, "Falha no upload: " + e.getMessage(), Toast.LENGTH_LONG).show();
android.util.Log.e("ProfileUpload", "Upload failed", e);
});
}

View File

@@ -44,7 +44,27 @@ public class ReservaAdapter extends RecyclerView.Adapter<ReservaAdapter.ViewHold
holder.txtStatus.setText("Estado: " + reserva.getEstado());
// Enable check-in only if confirmed
holder.btnCheckIn.setEnabled("Confirmada".equals(reserva.getEstado()));
boolean isConfirmed = "Confirmada".equals(reserva.getEstado());
boolean hasLocationPermission = androidx.core.app.ActivityCompat.checkSelfPermission(holder.itemView.getContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) == android.content.pm.PackageManager.PERMISSION_GRANTED;
if (isConfirmed) {
if (hasLocationPermission) {
holder.btnCheckIn.setEnabled(true);
if (holder.txtLocationWarning != null) {
holder.txtLocationWarning.setVisibility(View.GONE);
}
} else {
holder.btnCheckIn.setEnabled(false);
if (holder.txtLocationWarning != null) {
holder.txtLocationWarning.setVisibility(View.VISIBLE);
}
}
} else {
holder.btnCheckIn.setEnabled(false);
if (holder.txtLocationWarning != null) {
holder.txtLocationWarning.setVisibility(View.GONE);
}
}
// Show cancel only if not concluded or already cancelled/refused
boolean canCancel = "Pendente".equals(reserva.getEstado()) || "Confirmada".equals(reserva.getEstado());
@@ -67,7 +87,7 @@ public class ReservaAdapter extends RecyclerView.Adapter<ReservaAdapter.ViewHold
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView txtRestaurante, txtDataHora, txtStatus;
TextView txtRestaurante, txtDataHora, txtStatus, txtLocationWarning;
Button btnCheckIn, btnCancelar;
public ViewHolder(@NonNull View itemView) {
@@ -77,6 +97,7 @@ public class ReservaAdapter extends RecyclerView.Adapter<ReservaAdapter.ViewHold
txtStatus = itemView.findViewById(R.id.txtReservaStatus);
btnCheckIn = itemView.findViewById(R.id.btnCheckIn);
btnCancelar = itemView.findViewById(R.id.btnCancelar);
txtLocationWarning = itemView.findViewById(R.id.txtLocationWarning);
}
}
}

View File

@@ -3,10 +3,21 @@ package com.example.pap_teste;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.pap_teste.models.Restaurant;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.List;
public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.ViewHolder> {
@@ -25,7 +36,7 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_2, parent, false);
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_restaurant, parent, false);
return new ViewHolder(view);
}
@@ -40,6 +51,44 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
listener.onRestaurantClick(restaurant);
}
});
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null && user.getEmail() != null && restaurant.getEmail() != null) {
String encodedUserEmail = user.getEmail().replace(".", "_").replace("@", "_at_");
String encodedRestEmail = restaurant.getEmail().replace(".", "_").replace("@", "_at_");
DatabaseReference favRef = FirebaseDatabase.getInstance().getReference("users")
.child(encodedUserEmail).child("favorites").child(encodedRestEmail);
favRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_on);
} else {
holder.btnFavorite.setImageResource(android.R.drawable.btn_star_big_off);
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) { }
});
holder.btnFavorite.setOnClickListener(v -> {
favRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
favRef.removeValue();
} else {
favRef.setValue(restaurant);
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) { }
});
});
}
}
@Override
@@ -49,10 +98,12 @@ public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.Vi
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView text1, text2;
ImageButton btnFavorite;
public ViewHolder(@NonNull View itemView) {
super(itemView);
text1 = itemView.findViewById(android.R.id.text1);
text2 = itemView.findViewById(android.R.id.text2);
text1 = itemView.findViewById(R.id.txtRestaurantName);
text2 = itemView.findViewById(R.id.txtRestaurantCategory);
btnFavorite = itemView.findViewById(R.id.btnFavorite);
}
}
}

View File

@@ -6,6 +6,10 @@ public class Restaurant {
private String email;
private boolean available;
// No-argument constructor required for Firebase
public Restaurant() {
}
public Restaurant(String name, String category, String email, boolean available) {
this.name = name;
this.category = category;
@@ -17,4 +21,9 @@ public class Restaurant {
public String getCategory() { return category; }
public String getEmail() { return email; }
public boolean isAvailable() { return available; }
public void setName(String name) { this.name = name; }
public void setCategory(String category) { this.category = category; }
public void setEmail(String email) { this.email = email; }
public void setAvailable(boolean available) { this.available = available; }
}

View File

@@ -25,8 +25,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/circle_bg"
android:padding="8dp" />
android:src="@drawable/circle_bg" />
</androidx.cardview.widget.CardView>
<TextView

View File

@@ -65,71 +65,70 @@
android:orientation="vertical"
android:paddingBottom="32dp">
<!-- Section: Date -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:text="Escolha a data"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvDates"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingEnd="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
android:orientation="vertical"
android:paddingHorizontal="24dp"
android:layout_marginTop="16dp">
<!-- Section: Time -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:text="Escolha o horário"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Data da reserva"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvTimes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingEnd="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<Button
android:id="@+id/btnSelectDate"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="8dp"
android:background="@drawable/btn_light_border"
android:text="Selecionar Data"
android:textAllCaps="false"
android:textColor="#5F5F5F" />
<!-- Section: Party size -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:text="Número de pessoas"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Hora da reserva"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvPartySize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingEnd="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<Button
android:id="@+id/btnSelectTime"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="8dp"
android:background="@drawable/btn_light_border"
android:text="Selecionar Hora"
android:textAllCaps="false"
android:textColor="#5F5F5F" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Número de pessoas"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<EditText
android:id="@+id/etPartySize"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="8dp"
android:background="@drawable/btn_light_border"
android:inputType="number"
android:paddingHorizontal="16dp"
android:hint="Ex: 2"
android:textColor="#000" />
</LinearLayout>
<Button
android:id="@+id/btnConfirmarReserva"

View File

@@ -199,15 +199,46 @@
android:padding="12dp"
android:visibility="gone" />
<EditText
android:id="@+id/inputPassword"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="12dp"
android:background="@drawable/input_bg"
android:hint="Palavra-passe"
android:inputType="textPassword"
android:padding="12dp" />
android:layout_height="wrap_content"
android:layout_marginTop="12dp">
<EditText
android:id="@+id/inputPassword"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/input_bg"
android:hint="Palavra-passe"
android:inputType="textPassword"
android:paddingStart="12dp"
android:paddingEnd="48dp" />
<ImageView
android:id="@+id/iconPasswordVisibility"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:padding="12dp"
android:src="@drawable/ic_visibility_off"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackgroundBorderless" />
</RelativeLayout>
<TextView
android:id="@+id/txtForgotPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_gravity="end"
android:text="Esqueceu-se da palavra-passe?"
android:textColor="#1976D2"
android:textSize="14sp"
android:visibility="visible"
android:clickable="true"
android:focusable="true"/>
<Button
android:id="@+id/btnFinalCriarConta"

View File

@@ -74,71 +74,70 @@
android:orientation="vertical"
android:paddingBottom="32dp">
<!-- Section: Date -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:text="Escolha a data"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvDates"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingEnd="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
android:orientation="vertical"
android:paddingHorizontal="24dp"
android:layout_marginTop="16dp">
<!-- Section: Time -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:text="Escolha o horário"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Data da reserva"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvTimes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingEnd="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<Button
android:id="@+id/btnSelectDate"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="8dp"
android:background="@drawable/btn_light_border"
android:text="Selecionar Data"
android:textAllCaps="false"
android:textColor="#5F5F5F" />
<!-- Section: Party size -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:text="Número de pessoas"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Hora da reserva"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvPartySize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingEnd="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<Button
android:id="@+id/btnSelectTime"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="8dp"
android:background="@drawable/btn_light_border"
android:text="Selecionar Hora"
android:textAllCaps="false"
android:textColor="#5F5F5F" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Número de pessoas"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
<EditText
android:id="@+id/etPartySize"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="8dp"
android:background="@drawable/btn_light_border"
android:inputType="number"
android:paddingHorizontal="16dp"
android:hint="Ex: 2"
android:textColor="#000" />
</LinearLayout>
<Button
android:id="@+id/btnConfirmarReserva"

View File

@@ -69,5 +69,16 @@
android:background="@drawable/btn_light_border"
android:textColor="#C62828" />
</LinearLayout>
<TextView
android:id="@+id/txtLocationWarning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Dê permissões de localização para aceder ao check-in."
android:textAlignment="center"
android:textColor="#D32F2F"
android:textSize="12sp"
android:visibility="gone" />
</LinearLayout>
</androidx.cardview.widget.CardView>