This commit is contained in:
2026-04-29 10:37:57 +01:00
parent 097dbad215
commit b0b7a4087e
4 changed files with 101 additions and 13 deletions

View File

@@ -84,9 +84,55 @@ public class HomeFragment extends Fragment {
.navigate(com.example.cuida.R.id.action_home_to_schedule_appointment); .navigate(com.example.cuida.R.id.action_home_to_schedule_appointment);
}); });
// --- Feed Listener ---
loadFeed();
return binding.getRoot(); return binding.getRoot();
} }
private void loadFeed() {
com.google.firebase.auth.FirebaseAuth auth = com.google.firebase.auth.FirebaseAuth.getInstance();
if (auth.getCurrentUser() == null) return;
String userId = auth.getCurrentUser().getUid();
com.google.firebase.firestore.FirebaseFirestore.getInstance().collection("feed")
.whereEqualTo("userId", userId)
.orderBy("data", com.google.firebase.firestore.Query.Direction.DESCENDING)
.addSnapshotListener((value, error) -> {
if (error != null) return;
if (value != null && isAdded()) {
binding.layoutFeedContainer.removeAllViews();
if (value.isEmpty()) {
binding.layoutFeedContainer.addView(binding.textNoFeed);
} else {
for (com.google.firebase.firestore.DocumentSnapshot doc : value.getDocuments()) {
addFeedItem(doc);
}
}
}
});
}
private void addFeedItem(com.google.firebase.firestore.DocumentSnapshot doc) {
if (!isAdded()) return;
View itemView = getLayoutInflater().inflate(com.example.cuida.R.layout.item_feed, binding.layoutFeedContainer, false);
android.widget.TextView title = itemView.findViewById(com.example.cuida.R.id.feed_item_title);
android.widget.TextView content = itemView.findViewById(com.example.cuida.R.id.feed_item_content);
android.widget.TextView date = itemView.findViewById(com.example.cuida.R.id.feed_item_date);
title.setText(doc.getString("titulo"));
content.setText(doc.getString("conteudo"));
com.google.firebase.Timestamp ts = doc.getTimestamp("data");
if (ts != null) {
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("dd MMM, HH:mm", java.util.Locale.getDefault());
date.setText(sdf.format(ts.toDate()));
}
binding.layoutFeedContainer.addView(itemView);
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();

View File

@@ -79,9 +79,14 @@ public class ProfileFragment extends Fragment {
currentUser.name = auth.getCurrentUser().getDisplayName(); currentUser.name = auth.getCurrentUser().getDisplayName();
} }
db.collection("utilizadores").document(userId).get() db.collection("utilizadores").document(userId)
.addOnSuccessListener(doc -> { .addSnapshotListener((doc, error) -> {
if (doc.exists() && isAdded()) { if (error != null) {
Log.e("ProfileFragment", "Listen failed.", error);
return;
}
if (doc != null && doc.exists() && isAdded()) {
currentUser.id = doc.getId(); currentUser.id = doc.getId();
String nome = doc.getString("nome_completo"); String nome = doc.getString("nome_completo");
if (nome == null) nome = doc.getString("name"); if (nome == null) nome = doc.getString("name");

View File

@@ -64,7 +64,7 @@ public class ScheduleViewModel extends AndroidViewModel {
displayName += " - " + specialty; displayName += " - " + specialty;
} }
if (!displayName.startsWith("Dr.") && !displayName.startsWith("Dra.")) { if (!displayName.startsWith("Dr.") && !displayName.startsWith("Dra.")) {
if ("Feminino".equalsIgnoreCase(gender) || "Feminino".equals(gender)) { if ("Feminino".equalsIgnoreCase(gender)) {
displayName = "Dra. " + displayName; displayName = "Dra. " + displayName;
} else { } else {
displayName = "Dr. " + displayName; displayName = "Dr. " + displayName;
@@ -148,12 +148,17 @@ public class ScheduleViewModel extends AndroidViewModel {
timeSlots.setValue(generateTimeSlots(new ArrayList<>(), date)); timeSlots.setValue(generateTimeSlots(new ArrayList<>(), date));
if (auth.getCurrentUser() == null) return; if (auth.getCurrentUser() == null) return;
String userId = auth.getCurrentUser().getUid();
String doctor = selectedDoctor.getValue(); String doctor = selectedDoctor.getValue();
// Listen in REAL-TIME for all appointments on the selected date if (doctor == null) {
timeSlots.setValue(generateTimeSlots(new ArrayList<>(), date));
return;
}
// Listen in REAL-TIME for appointments of the selected doctor on the selected date
snapshotListener = db.collection("consultas") snapshotListener = db.collection("consultas")
.whereEqualTo("date", date) .whereEqualTo("date", date)
.whereEqualTo("type", doctor)
.addSnapshotListener((queryDocumentSnapshots, e) -> { .addSnapshotListener((queryDocumentSnapshots, e) -> {
if (e != null) { if (e != null) {
Log.e("ScheduleViewModel", "Listen failed.", e); Log.e("ScheduleViewModel", "Listen failed.", e);
@@ -164,16 +169,11 @@ public class ScheduleViewModel extends AndroidViewModel {
if (queryDocumentSnapshots != null) { if (queryDocumentSnapshots != null) {
for (QueryDocumentSnapshot document : queryDocumentSnapshots) { for (QueryDocumentSnapshot document : queryDocumentSnapshots) {
Appointment appt = document.toObject(Appointment.class); Appointment appt = document.toObject(Appointment.class);
if (appt.time != null && !bookedTimes.contains(appt.time)) {
boolean isDoctorAppointment = doctor != null && doctor.equals(appt.type);
if (isDoctorAppointment && appt.time != null) {
if (!bookedTimes.contains(appt.time)) {
bookedTimes.add(appt.time); bookedTimes.add(appt.time);
} }
} }
} }
}
List<TimeSlot> slots = generateTimeSlots(bookedTimes, date); List<TimeSlot> slots = generateTimeSlots(bookedTimes, date);
timeSlots.setValue(slots); timeSlots.setValue(slots);

View File

@@ -84,4 +84,41 @@
app:iconGravity="textStart" app:iconGravity="textStart"
app:layout_constraintTop_toBottomOf="@id/card_next_medication"/> app:layout_constraintTop_toBottomOf="@id/card_next_medication"/>
<TextView
android:id="@+id/text_feed_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Feed Clínico"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/primary_color"
android:layout_marginTop="24dp"
app:layout_constraintTop_toBottomOf="@id/button_book_appointment"
app:layout_constraintStart_toStartOf="parent"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@id/text_feed_title"
app:layout_constraintBottom_toBottomOf="parent">
<LinearLayout
android:id="@+id/layout_feed_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/text_no_feed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sem novos relatórios ou atualizações."
android:textAlignment="center"
android:padding="24dp"
android:textColor="@android:color/darker_gray"/>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>