diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml
index 8efc3b6..5a9ece8 100644
--- a/.idea/caches/deviceStreaming.xml
+++ b/.idea/caches/deviceStreaming.xml
@@ -1464,6 +1464,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/fluxup/app/SearchFragment.java b/app/src/main/java/com/fluxup/app/SearchFragment.java
index 7e691fa..064fa57 100644
--- a/app/src/main/java/com/fluxup/app/SearchFragment.java
+++ b/app/src/main/java/com/fluxup/app/SearchFragment.java
@@ -1,56 +1,333 @@
package com.fluxup.app;
+import android.graphics.Color;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
-import android.widget.ListView;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.github.mikephil.charting.charts.BarChart;
+import com.github.mikephil.charting.components.XAxis;
+import com.github.mikephil.charting.data.BarData;
+import com.github.mikephil.charting.data.BarDataSet;
+import com.github.mikephil.charting.data.BarEntry;
+import com.github.mikephil.charting.formatter.ValueFormatter;
+import com.google.firebase.auth.FirebaseAuth;
+import com.google.firebase.firestore.FirebaseFirestore;
+import com.google.firebase.firestore.Query;
+
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
public class SearchFragment extends Fragment {
- private ListView recyclerView;
private EditText searchBar;
- private ArrayAdapter adapter;
- private ArrayList allItems;
+ private BarChart weeklyChart;
+ private TextView tvEmptyState;
+ private RecyclerView rvChallenges, rvFeaturedUsers;
+ private ChallengeAdapter challengeAdapter;
+ private FeaturedUserAdapter userAdapter;
+
+ private final FirestoreManager firestoreManager = FirestoreManager.getInstance();
+ private final String currentUserId = FirebaseAuth.getInstance().getUid();
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_search, container, false);
- recyclerView = view.findViewById(R.id.recycler_view);
- searchBar = view.findViewById(R.id.search_bar);
-
- allItems = new ArrayList<>(Arrays.asList("Item 1", "Item 2", "Item 3", "Another Item", "More Items"));
-
- adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, allItems);
- recyclerView.setAdapter(adapter);
-
- searchBar.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- adapter.getFilter().filter(s);
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- }
- });
+ initViews(view);
+ setupCharts();
+ setupRecyclerViews();
+ loadData();
+ setupSearch();
return view;
}
+
+ private void initViews(View view) {
+ searchBar = view.findViewById(R.id.search_bar);
+ weeklyChart = view.findViewById(R.id.weeklyChart);
+ tvEmptyState = view.findViewById(R.id.tvEmptyState);
+ rvChallenges = view.findViewById(R.id.rvChallenges);
+ rvFeaturedUsers = view.findViewById(R.id.rvFeaturedUsers);
+ }
+
+ private void setupCharts() {
+ weeklyChart.getDescription().setEnabled(false);
+ weeklyChart.getLegend().setEnabled(false);
+ weeklyChart.setDrawGridBackground(false);
+ weeklyChart.setDrawBarShadow(false);
+ weeklyChart.setDrawValueAboveBar(true);
+ weeklyChart.setTouchEnabled(false);
+
+ XAxis xAxis = weeklyChart.getXAxis();
+ xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
+ xAxis.setDrawGridLines(false);
+ xAxis.setGranularity(1f);
+ xAxis.setTextColor(Color.parseColor("#94A3B8"));
+
+ String[] days = {"SEG", "TER", "QUA", "QUI", "SEX", "SAB", "DOM"};
+ xAxis.setValueFormatter(new ValueFormatter() {
+ @Override
+ public String getFormattedValue(float value) {
+ int index = (int) value;
+ if (index >= 0 && index < days.length) return days[index];
+ return "";
+ }
+ });
+
+ weeklyChart.getAxisLeft().setDrawGridLines(true);
+ weeklyChart.getAxisLeft().setGridColor(Color.parseColor("#E2E8F0"));
+ weeklyChart.getAxisLeft().setTextColor(Color.parseColor("#94A3B8"));
+ weeklyChart.getAxisRight().setEnabled(false);
+ }
+
+ private void setupRecyclerViews() {
+ // Challenges
+ rvChallenges.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
+ challengeAdapter = new ChallengeAdapter(getMockChallenges());
+ rvChallenges.setAdapter(challengeAdapter);
+
+ // Featured Users
+ rvFeaturedUsers.setLayoutManager(new LinearLayoutManager(getContext()));
+ userAdapter = new FeaturedUserAdapter(new ArrayList<>());
+ rvFeaturedUsers.setAdapter(userAdapter);
+ }
+
+ private void setupSearch() {
+ searchBar.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ filterUsers(s.toString());
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {}
+ });
+ }
+
+ private void loadData() {
+ if (currentUserId == null) return;
+
+ // Load Weekly Progress
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ Date startDate = cal.getTime();
+
+ cal.add(Calendar.DAY_OF_WEEK, 6);
+ cal.set(Calendar.HOUR_OF_DAY, 23);
+ cal.set(Calendar.MINUTE, 59);
+ cal.set(Calendar.SECOND, 59);
+ Date endDate = cal.getTime();
+
+ firestoreManager.getDailyProgress(currentUserId, startDate, endDate, 3, progressMap -> {
+ updateChart(progressMap);
+ });
+
+ // Load Featured Users (mocking top users from Firestore)
+ FirebaseFirestore.getInstance().collection("users")
+ .orderBy("xp", Query.Direction.DESCENDING)
+ .limit(10)
+ .get()
+ .addOnSuccessListener(snapshots -> {
+ List users = new ArrayList<>();
+ for (com.google.firebase.firestore.DocumentSnapshot doc : snapshots) {
+ Usuario u = doc.toObject(Usuario.class);
+ if (u != null) users.add(u);
+ }
+ userAdapter.updateList(users);
+ });
+ }
+
+ private void updateChart(Map progressMap) {
+ if (progressMap.isEmpty()) {
+ weeklyChart.setVisibility(View.GONE);
+ tvEmptyState.setVisibility(View.VISIBLE);
+ return;
+ }
+
+ weeklyChart.setVisibility(View.VISIBLE);
+ tvEmptyState.setVisibility(View.GONE);
+
+ List entries = new ArrayList<>();
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+
+ int todayIndex = Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 2;
+ if (todayIndex < 0) todayIndex = 6; // Sunday fix
+
+ List colors = new ArrayList<>();
+
+ for (int i = 0; i < 7; i++) {
+ String dateStr = sdf.format(cal.getTime());
+ DailyProgress dp = progressMap.get(dateStr);
+ int xp = (dp != null) ? dp.xp : 0;
+ entries.add(new BarEntry(i, xp));
+
+ if (i == todayIndex) {
+ colors.add(Color.parseColor("#7C3AED")); // Roxo principal destaque
+ } else {
+ colors.add(Color.parseColor("#DDD6FE")); // Roxo claro
+ }
+ cal.add(Calendar.DAY_OF_WEEK, 1);
+ }
+
+ BarDataSet dataSet = new BarDataSet(entries, "XP");
+ dataSet.setColors(colors);
+ dataSet.setDrawValues(true);
+ dataSet.setValueTextColor(Color.parseColor("#7C3AED"));
+ dataSet.setValueTextSize(10f);
+
+ BarData data = new BarData(dataSet);
+ data.setBarWidth(0.6f);
+
+ weeklyChart.setData(data);
+ weeklyChart.animateY(1000);
+ weeklyChart.invalidate();
+ }
+
+ private void filterUsers(String query) {
+ userAdapter.filter(query);
+ }
+
+ private List getMockChallenges() {
+ List list = new ArrayList<>();
+ list.add(new Challenge("🎯", "7 dias sem procrastinar", 500));
+ list.add(new Challenge("📚", "Ler 20 min por dia", 300));
+ list.add(new Challenge("⏱️", "30 min foco diário", 400));
+ return list;
+ }
+
+ // --- ADAPTERS ---
+
+ private static class Challenge {
+ String icon, name;
+ int xp;
+ Challenge(String icon, String name, int xp) {
+ this.icon = icon; this.name = name; this.xp = xp;
+ }
+ }
+
+ private class ChallengeAdapter extends RecyclerView.Adapter {
+ private final List items;
+ ChallengeAdapter(List items) { this.items = items; }
+
+ @NonNull
+ @Override
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_challenge, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+ Challenge item = items.get(position);
+ holder.icon.setText(item.icon);
+ holder.name.setText(item.name);
+ holder.xp.setText("+" + item.xp + " XP");
+ holder.btn.setOnClickListener(v -> Toast.makeText(getContext(), "Desafio iniciado!", Toast.LENGTH_SHORT).show());
+ }
+
+ @Override
+ public int getItemCount() { return items.size(); }
+
+ class ViewHolder extends RecyclerView.ViewHolder {
+ TextView icon, name, xp;
+ View btn;
+ ViewHolder(View v) {
+ super(v);
+ icon = v.findViewById(R.id.tvChallengeIcon);
+ name = v.findViewById(R.id.tvChallengeName);
+ xp = v.findViewById(R.id.tvChallengeXP);
+ btn = v.findViewById(R.id.btnStartChallenge);
+ }
+ }
+ }
+
+ private class FeaturedUserAdapter extends RecyclerView.Adapter {
+ private List items;
+ private List fullList;
+
+ FeaturedUserAdapter(List items) {
+ this.items = items;
+ this.fullList = new ArrayList<>(items);
+ }
+
+ void updateList(List newList) {
+ this.items = newList;
+ this.fullList = new ArrayList<>(newList);
+ notifyDataSetChanged();
+ }
+
+ void filter(String query) {
+ if (query.isEmpty()) {
+ items = new ArrayList<>(fullList);
+ } else {
+ items = new ArrayList<>();
+ for (Usuario u : fullList) {
+ if (u.usuario.toLowerCase().contains(query.toLowerCase())) {
+ items.add(u);
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ @NonNull
+ @Override
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_featured_user, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+ Usuario user = items.get(position);
+ holder.name.setText(user.usuario);
+ holder.stats.setText("🔥 " + user.streak + " dias • " + user.league);
+ // holder.avatar setup if needed
+ holder.btnAdd.setOnClickListener(v -> Toast.makeText(getContext(), "Pedido enviado!", Toast.LENGTH_SHORT).show());
+ }
+
+ @Override
+ public int getItemCount() { return items.size(); }
+
+ class ViewHolder extends RecyclerView.ViewHolder {
+ ImageView avatar;
+ TextView name, stats;
+ View btnAdd;
+ ViewHolder(View v) {
+ super(v);
+ avatar = v.findViewById(R.id.ivUserAvatar);
+ name = v.findViewById(R.id.tvUserName);
+ stats = v.findViewById(R.id.tvUserStats);
+ btnAdd = v.findViewById(R.id.btnAddFriend);
+ }
+ }
+ }
}
diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml
index c235cef..72a5f27 100644
--- a/app/src/main/res/layout/fragment_search.xml
+++ b/app/src/main/res/layout/fragment_search.xml
@@ -1,18 +1,151 @@
-
-
+
+ android:layout_height="match_parent"
+ android:background="@color/background_light"
+ android:fillViewport="true">
-
+ android:orientation="vertical"
+ android:paddingHorizontal="20dp"
+ android:paddingTop="20dp"
+ android:paddingBottom="80dp">
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+