Juegos finalizados, haciendo aplicacion movil para los trabajadores

This commit is contained in:
Andrés Moran 2025-04-26 22:13:48 +02:00
parent bdd2203bcb
commit b616edef1f
472 changed files with 7826 additions and 1573 deletions

View File

@ -4,10 +4,10 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-04-02T22:29:52.881951Z"> <DropdownSelection timestamp="2025-04-18T20:03:38.478308800Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=104958790502" /> <DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\moran\.android\avd\Pixel_9_Pro.avd" />
</handle> </handle>
</Target> </Target>
</DropdownSelection> </DropdownSelection>

View File

@ -2,7 +2,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application <application
android:networkSecurityConfig="@xml/network_security_config"
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"

View File

@ -0,0 +1,10 @@
package com.andresgmoran.apptrabajadores.interfaces;
import com.andresgmoran.apptrabajadores.models.Activity;
import com.andresgmoran.apptrabajadores.models.ActivityResident;
import java.util.List;
public interface IOClickOnActivityListener {
void onClickOnActivity(Activity activity, List<ActivityResident> activityResidents);
}

View File

@ -0,0 +1,7 @@
package com.andresgmoran.apptrabajadores.interfaces;
import com.andresgmoran.apptrabajadores.models.Game;
public interface IOClickOnGameListener {
void onClickOnGame(Game game);
}

View File

@ -0,0 +1,9 @@
package com.andresgmoran.apptrabajadores.interfaces;
import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
public interface IOClickOnGameStatsListener {
void onClickOnLatestGame(GameStat gameStat, Resident gameStatResident, Game gameStatGame);
}

View File

@ -1,8 +0,0 @@
package com.andresgmoran.apptrabajadores.interfaces;
import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.LastGame;
public interface IOClickOnLatestGameListener {
void onClickOnLatestGame(LastGame game);
}

View File

@ -0,0 +1,50 @@
package com.andresgmoran.apptrabajadores.models;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
public class Activity implements Serializable {
private final String name;
private final String description;
private final LocalDate date;
private final ActivityState state;
private final List<Resident> residents;
public Activity(String name, String description, LocalDate date, ActivityState state, List<Resident> residents) {
this.name = name;
this.description = description;
this.date = date;
this.state = state;
this.residents = residents;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public LocalDate getDate() {
return date;
}
public ActivityState getState() {
return state;
}
public List<Resident> getResidents() {
return residents;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Activity activity = (Activity) o;
return Objects.equals(name, activity.name) && Objects.equals(description, activity.description) && Objects.equals(date, activity.date) && state == activity.state && Objects.equals(residents, activity.residents);
}
@Override
public int hashCode() {
return Objects.hash(name, description, date, state, residents);
}
}

View File

@ -0,0 +1,48 @@
package com.andresgmoran.apptrabajadores.models;
import java.time.LocalDate;
import java.util.Objects;
public class ActivityResident extends Resident{
private boolean asistanceState;
private String preOpinion;
private String postOpinion;
public ActivityResident(Long id, String name, String surnames, LocalDate birthDate, Long residenceId, boolean asistanceState, String preOpinion, String postOpinion) {
super(id, name, surnames, birthDate, residenceId);
this.asistanceState = asistanceState;
this.preOpinion = preOpinion;
this.postOpinion = postOpinion;
}
public boolean isAsistanceState() {
return asistanceState;
}
public void setAsistanceState(boolean asistanceState) {
this.asistanceState = asistanceState;
}
public String getPreOpinion() {
return preOpinion;
}
public void setPreOpinion(String preOpinion) {
this.preOpinion = preOpinion;
}
public String getPostOpinion() {
return postOpinion;
}
public void setPostOpinion(String postOpinion) {
this.postOpinion = postOpinion;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
ActivityResident that = (ActivityResident) o;
return asistanceState == that.asistanceState && Objects.equals(preOpinion, that.preOpinion) && Objects.equals(postOpinion, that.postOpinion);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), asistanceState, preOpinion, postOpinion);
}
}

View File

@ -0,0 +1,19 @@
package com.andresgmoran.apptrabajadores.models;
import com.andresgmoran.apptrabajadores.models.gameStats.Difficulty;
public enum ActivityState {
ABIERTO,
CERRADO;
public static ActivityState fromString(String value) {
switch (value.toLowerCase()) {
case "abierto":
return ABIERTO;
case "cerrado":
return CERRADO;
default:
throw new IllegalArgumentException("Valor de estado no válido: " + value);
}
}
}

View File

@ -1,54 +0,0 @@
package com.andresgmoran.apptrabajadores.models;
import java.util.Date;
import java.util.Objects;
public class FollowTheLineGame extends Game{
private double accuracy;
private int timeOutOfLine;
private int totalOfShapes;
public FollowTheLineGame(String name, Date startOfGame, Date endOfGame, Resident resident, Worker worker, double accuracy, int timeOutOfLine, int totalOfShapes) {
super(name, startOfGame, endOfGame, resident, worker);
this.accuracy = accuracy;
this.timeOutOfLine = timeOutOfLine;
this.totalOfShapes = totalOfShapes;
}
public double getAccuracy() {
return accuracy;
}
public void setAccuracy(double accuracy) {
this.accuracy = accuracy;
}
public int getTimeOutOfLine() {
return timeOutOfLine;
}
public void setTimeOutOfLine(int timeOutOfLine) {
this.timeOutOfLine = timeOutOfLine;
}
public int getTotalOfShapes() {
return totalOfShapes;
}
public void setTotalOfShapes(int totalOfShapes) {
this.totalOfShapes = totalOfShapes;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
FollowTheLineGame that = (FollowTheLineGame) o;
return Double.compare(accuracy, that.accuracy) == 0 && timeOutOfLine == that.timeOutOfLine && totalOfShapes == that.totalOfShapes;
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), accuracy, timeOutOfLine, totalOfShapes);
}
}

View File

@ -1,68 +1,41 @@
package com.andresgmoran.apptrabajadores.models; package com.andresgmoran.apptrabajadores.models;
import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.Objects; import java.util.Objects;
public class Game { public class Game implements Serializable {
private String name; private final Long id;
private Date startOfGame; private final String name;
private Date endOfGame; private final Long residenceId;
private Resident resident;
private Worker worker;
public Game(String name, Date startOfGame, Date endOfGame, Resident resident, Worker worker) { public Game(Long id, String name, Long residenceId) {
this.id = id;
this.name = name; this.name = name;
this.startOfGame = startOfGame; this.residenceId = residenceId;
this.endOfGame = endOfGame; }
this.resident = resident;
this.worker = worker; public Long getId() {
return id;
} }
public String getName() { public String getName() {
return name; return name;
} }
public Date getStartOfGame() { public Long getResidenceId() {
return startOfGame; return residenceId;
}
public void setStartOfGame(Date startOfGame) {
this.startOfGame = startOfGame;
}
public Date getEndOfGame() {
return endOfGame;
}
public void setEndOfGame(Date endOfGame) {
this.endOfGame = endOfGame;
}
public Resident getResident() {
return resident;
}
public void setResident(Resident resident) {
this.resident = resident;
}
public Worker getWorker() {
return worker;
}
public void setWorker(Worker worker) {
this.worker = worker;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
Game game = (Game) o; Game game = (Game) o;
return Objects.equals(startOfGame, game.startOfGame) && Objects.equals(endOfGame, game.endOfGame) && Objects.equals(resident, game.resident) && Objects.equals(worker, game.worker); return Objects.equals(id, game.id) && Objects.equals(name, game.name) && Objects.equals(residenceId, game.residenceId);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(startOfGame, endOfGame, resident, worker); return Objects.hash(id, name, residenceId);
} }
} }

View File

@ -1,40 +0,0 @@
package com.andresgmoran.apptrabajadores.models;
import java.util.Date;
import java.util.Objects;
public class LastGame {
private final Resident resident;
private final Game game;
private final Date date;
public LastGame(Resident resident, Game game, Date date) {
this.resident = resident;
this.game = game;
this.date = date;
}
public Resident getResident() {
return resident;
}
public Game getGame() {
return game;
}
public Date getDate() {
return date;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
LastGame lastGame = (LastGame) o;
return Objects.equals(resident, lastGame.resident) && Objects.equals(game, lastGame.game) && Objects.equals(date, lastGame.date);
}
@Override
public int hashCode() {
return Objects.hash(resident, game, date);
}
}

View File

@ -3,15 +3,15 @@ package com.andresgmoran.apptrabajadores.models;
import java.util.Objects; import java.util.Objects;
public class Observation { public class Observation {
private final Worker observationOwner; private final User observationOwner;
private final String observationText; private final String observationText;
public Observation(Worker observationOwner, String observationText) { public Observation(User observationOwner, String observationText) {
this.observationOwner = observationOwner; this.observationOwner = observationOwner;
this.observationText = observationText; this.observationText = observationText;
} }
public Worker getObservationOwner() { public User getObservationOwner() {
return observationOwner; return observationOwner;
} }

View File

@ -1,17 +1,27 @@
package com.andresgmoran.apptrabajadores.models; package com.andresgmoran.apptrabajadores.models;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Date; import java.util.Date;
import java.util.Objects; import java.util.Objects;
public class Resident { public class Resident implements Serializable {
private final Long id;
private final String name; private final String name;
private final String surnames; private final String surnames;
private final String birthDate; private final LocalDate birthDate;
private final Long residenceId;
public Resident(String name, String surnames, String birthDate) { public Resident(Long id, String name, String surnames, LocalDate birthDate, Long residenceId) {
this.id = id;
this.name = name; this.name = name;
this.surnames = surnames; this.surnames = surnames;
this.birthDate = birthDate; this.birthDate = birthDate;
this.residenceId = residenceId;
}
public Long getId() {
return id;
} }
public String getName() { public String getName() {
@ -22,19 +32,23 @@ public class Resident {
return surnames; return surnames;
} }
public String getBirthDate() { public LocalDate getBirthDate() {
return birthDate; return birthDate;
} }
public Long getResidenceId() {
return residenceId;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
Resident resident = (Resident) o; Resident resident = (Resident) o;
return Objects.equals(name, resident.name) && Objects.equals(surnames, resident.surnames) && Objects.equals(birthDate, resident.birthDate); return Objects.equals(id, resident.id) && Objects.equals(name, resident.name) && Objects.equals(surnames, resident.surnames) && Objects.equals(birthDate, resident.birthDate) && Objects.equals(residenceId, resident.residenceId);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(name, surnames, birthDate); return Objects.hash(id, name, surnames, birthDate, residenceId);
} }
} }

View File

@ -0,0 +1,65 @@
package com.andresgmoran.apptrabajadores.models;
import java.io.Serializable;
import java.util.Objects;
public class User implements Serializable {
private final Long id;
private final String name;
private final String surnames;
private final String email;
private final boolean enabled;
private final Long residenceId;
private final String role; //Decirle a kevin que lo ponga
public User(Long id, String name, String surnames, String email, boolean enabled, Long residenceId) {
this.id = id;
this.name = name;
this.surnames = surnames;
this.email = email;
this.enabled = enabled;
this.residenceId = residenceId;
this.role = "Trabajador";
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public String getSurnames() {
return surnames;
}
public String getEmail() {
return email;
}
public boolean isEnabled() {
return enabled;
}
public Long getResidenceId() {
return residenceId;
}
public String getRole() {
return role;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return enabled == user.enabled && Objects.equals(id, user.id) && Objects.equals(name, user.name) && Objects.equals(surnames, user.surnames) && Objects.equals(email, user.email) && Objects.equals(residenceId, user.residenceId) && Objects.equals(role, user.role);
}
@Override
public int hashCode() {
return Objects.hash(id, name, surnames, email, enabled, residenceId, role);
}
}

View File

@ -1,39 +0,0 @@
package com.andresgmoran.apptrabajadores.models;
import java.util.Objects;
public class Worker {
private final String name;
private final String surnames;
private final String role;
public Worker(String name, String surnames, String role) {
this.name = name;
this.surnames = surnames;
this.role = role;
}
public String getName() {
return name;
}
public String getSurnames() {
return surnames;
}
public String getJob() {
return role;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Worker worker = (Worker) o;
return Objects.equals(name, worker.name) && Objects.equals(surnames, worker.surnames) && Objects.equals(role, worker.role);
}
@Override
public int hashCode() {
return Objects.hash(name, surnames, role);
}
}

View File

@ -0,0 +1,49 @@
package com.andresgmoran.apptrabajadores.models.adapters;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.models.Game;
public class ActivitiesAdapter extends RecyclerView.Adapter<ActivitiesAdapter.ActivitiesViewHolder> {
public ActivitiesAdapter(){
// Constructor implementation
}
@NonNull
@Override
public ActivitiesAdapter.ActivitiesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
final View view = LayoutInflater.from( parent.getContext()).inflate(R.layout.item_resident_activity, parent, false);
return new ActivitiesAdapter.ActivitiesViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ActivitiesViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
}
@Override
public int getItemCount() {
return 0;
}
public class ActivitiesViewHolder extends RecyclerView.ViewHolder {
public ActivitiesViewHolder(View view) {
super(view);
}
}
}

View File

@ -0,0 +1,64 @@
package com.andresgmoran.apptrabajadores.models.adapters;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameListener;
import com.andresgmoran.apptrabajadores.models.Game;
import java.util.List;
public class GamesAdapter extends RecyclerView.Adapter<GamesAdapter.GamesViewHolder>{
private final List<Game> games;
private final IOClickOnGameListener listener;
public GamesAdapter(List<Game> games, IOClickOnGameListener listener) {
this.games = games;
this.listener = listener;
}
@NonNull
@Override
public GamesAdapter.GamesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
final View view = LayoutInflater.from( parent.getContext()).inflate(R.layout.item_list_container, parent, false);
return new GamesAdapter.GamesViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull GamesAdapter.GamesViewHolder holder, int position) {
Game game = games.get(position);
holder.bindGame(game);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onClickOnGame(game);
}
});
}
public int getItemCount() {
return games != null ? games.size() : 0;
}
public class GamesViewHolder extends RecyclerView.ViewHolder {
private final TextView gameName;
public GamesViewHolder(View view) {
super(view);
gameName = view.findViewById(R.id.name_list_item);
}
public void bindGame(Game game) {
gameName.setText(game.getName());
}
}
}

View File

@ -1,5 +1,6 @@
package com.andresgmoran.apptrabajadores.models.adapters; package com.andresgmoran.apptrabajadores.models.adapters;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -9,60 +10,122 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.andresgmoran.apptrabajadores.R; import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnLatestGameListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameStatsListener;
import com.andresgmoran.apptrabajadores.models.LastGame; import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Locale;
public class LastGamesAdapter extends RecyclerView.Adapter<LastGamesAdapter.LastGamesViewHolder> { public class LastGamesAdapter extends RecyclerView.Adapter<LastGamesAdapter.LastGamesViewHolder> {
private List<LastGame> lastGames;
private IOClickOnLatestGameListener listener;
public LastGamesAdapter(List<LastGame> lastGames, IOClickOnLatestGameListener listener) { private final List<GameStat> gameStats;
this.lastGames = lastGames; private final List<Game> games;
private final List<Resident> residents;
private final IOClickOnGameStatsListener listener;
// Constructor para varios residentes
public LastGamesAdapter(List<GameStat> gameStats, List<Game> games, List<Resident> residents, IOClickOnGameStatsListener listener) {
this.gameStats = gameStats;
this.games = games;
this.residents = residents;
this.listener = listener; this.listener = listener;
this.gameStats.sort(Comparator.comparing(GameStat::getDateTime).reversed());
}
// Constructor para un solo un residente
public LastGamesAdapter(List<GameStat> gameStats, List<Game> games, Resident resident, IOClickOnGameStatsListener listener) {
this(gameStats, games, List.of(resident), listener);
}
// Constructor para un solo juego
public LastGamesAdapter(List<GameStat> gameStats, Game game, List<Resident> residents, IOClickOnGameStatsListener listener) {
this(gameStats, List.of(game), residents, listener);
} }
@NonNull @NonNull
@Override @Override
public LastGamesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public LastGamesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
final View view = LayoutInflater.from( parent.getContext()).inflate(R.layout.item_latest_game, parent, false); View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_latest_game, parent, false);
return new LastGamesViewHolder(view); return new LastGamesViewHolder(view);
} }
@Override @Override
public void onBindViewHolder(@NonNull LastGamesViewHolder holder, int position) { public void onBindViewHolder(@NonNull LastGamesViewHolder holder, int position) {
LastGame lastGame = lastGames.get(position); GameStat gameStat = gameStats.get(position);
holder.bindObservation(lastGame);
holder.itemView.setOnClickListener(new View.OnClickListener() { Resident gameStatResident = null;
@Override for (Resident resident : residents) {
public void onClick(View view) { if (resident.getId().equals(gameStat.getResidentId())) {
listener.onClickOnLatestGame(lastGame); gameStatResident = resident;
break;
} }
}
Game gameStatGame = null;
for (Game game : games) {
if (game.getId().equals(gameStat.getGameId())) {
gameStatGame = game;
break;
}
}
holder.bindObservation(gameStat, gameStatResident, gameStatGame);
Resident finalGameStatResident = gameStatResident;
Game finalGameStatGame = gameStatGame;
holder.itemView.setOnClickListener(v -> {
if (finalGameStatResident != null && finalGameStatGame != null)
listener.onClickOnLatestGame(gameStat, finalGameStatResident, finalGameStatGame);
}); });
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return lastGames.size(); return gameStats.size();
} }
public class LastGamesViewHolder extends RecyclerView.ViewHolder { public class LastGamesViewHolder extends RecyclerView.ViewHolder {
private TextView residentName; private final TextView residentName;
private TextView gameName; private final TextView gameName;
private TextView date; private final TextView date;
private final TextView time;
public LastGamesViewHolder(View view) { public LastGamesViewHolder(View view) {
super(view); super(view);
residentName = view.findViewById(R.id.name_text_latestGameItem); residentName = view.findViewById(R.id.name_text_latestGameItem);
gameName = view.findViewById(R.id.gameName_text_latestGameItem); gameName = view.findViewById(R.id.gameName_text_latestGameItem);
date = view.findViewById(R.id.date_text_latestGameItem); date = view.findViewById(R.id.date_text_latestGameItem);
time = view.findViewById(R.id.time_text_latestGameItem);
} }
public void bindObservation(LastGame lastGame){
residentName.setText(lastGame.getResident().getName()); public void bindObservation(GameStat gameStat, Resident gameStatResident, Game gameStatGame) {
gameName.setText(lastGame.getGame().getName()); if (gameStatResident == null || gameStatGame == null) {
residentName.setText("Residente no encontrado");
gameName.setText("Juego desconocido");
date.setText("-");
time.setText("-");
return;
}
residentName.setText(gameStatResident.getName() + " " + gameStatResident.getSurnames());
gameName.setText(gameStatGame.getName());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE, d 'de' MMMM 'de' yyyy", new Locale("es", "ES"));
String fechaFormateada = gameStat.getDateTime().format(formatter);
fechaFormateada = fechaFormateada.substring(0, 1).toUpperCase() + fechaFormateada.substring(1);
date.setText(fechaFormateada);
DateTimeFormatter formatterHora = DateTimeFormatter.ofPattern("h:mma", Locale.ENGLISH);
String horaFormateada = gameStat.getDateTime().format(formatterHora).toLowerCase();
time.setText(horaFormateada);
} }
} }
} }

View File

@ -12,10 +12,9 @@ import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.models.Observation; import com.andresgmoran.apptrabajadores.models.Observation;
import java.util.List; import java.util.List;
import java.util.Objects;
public class ObservationsAdapter extends RecyclerView.Adapter<ObservationsAdapter.ObservationsViewHolder> { public class ObservationsAdapter extends RecyclerView.Adapter<ObservationsAdapter.ObservationsViewHolder> {
private List<Observation> observations; private final List<Observation> observations;
public ObservationsAdapter(List<Observation> observations){ public ObservationsAdapter(List<Observation> observations){
this.observations = observations; this.observations = observations;
@ -41,19 +40,18 @@ public class ObservationsAdapter extends RecyclerView.Adapter<ObservationsAdapte
public class ObservationsViewHolder extends RecyclerView.ViewHolder { public class ObservationsViewHolder extends RecyclerView.ViewHolder {
private TextView observation; private final TextView observation;
private TextView observationOwner; private final TextView observationOwner;
private TextView observationOwnerRole; private final TextView observationOwnerRole;
public ObservationsViewHolder(View view) { public ObservationsViewHolder(View view) {
super(view); super(view);
observation = view.findViewById(R.id.observation_text); observation = view.findViewById(R.id.observation_text);
observationOwner = view.findViewById(R.id.observation_person_name); observationOwner = view.findViewById(R.id.home_user_name);
observationOwnerRole = view.findViewById(R.id.observation_person_role); observationOwnerRole = view.findViewById(R.id.observation_person_role);
} }
public void bindObservation(Observation observation){ public void bindObservation(Observation observation){
observationOwner.setText(observation.getObservationOwner().getName()); observationOwner.setText(observation.getObservationOwner().getName());
observationOwnerRole.setText(observation.getObservationOwner().getJob());
this.observation.setText(observation.getObservationText()); this.observation.setText(observation.getObservationText());
} }
} }

View File

@ -9,15 +9,14 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.andresgmoran.apptrabajadores.R; import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.interfaces.IOChangeFragmentListener;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnResidentListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnResidentListener;
import com.andresgmoran.apptrabajadores.models.Resident; import com.andresgmoran.apptrabajadores.models.Resident;
import java.util.List; import java.util.List;
public class ResidentsAdapter extends RecyclerView.Adapter<ResidentsAdapter.ResidentsViewHolder> { public class ResidentsAdapter extends RecyclerView.Adapter<ResidentsAdapter.ResidentsViewHolder> {
private List<Resident> residents; private final List<Resident> residents;
private IOClickOnResidentListener listener; private final IOClickOnResidentListener listener;
public ResidentsAdapter(List<Resident> residents, IOClickOnResidentListener listener) { public ResidentsAdapter(List<Resident> residents, IOClickOnResidentListener listener) {
this.residents = residents; this.residents = residents;
@ -27,7 +26,7 @@ public class ResidentsAdapter extends RecyclerView.Adapter<ResidentsAdapter.Resi
@NonNull @NonNull
@Override @Override
public ResidentsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ResidentsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
final View view = LayoutInflater.from( parent.getContext()).inflate(R.layout.item_resident, parent, false); final View view = LayoutInflater.from( parent.getContext()).inflate(R.layout.item_list_container, parent, false);
return new ResidentsViewHolder(view); return new ResidentsViewHolder(view);
} }
@ -44,9 +43,8 @@ public class ResidentsAdapter extends RecyclerView.Adapter<ResidentsAdapter.Resi
}); });
} }
@Override
public int getItemCount() { public int getItemCount() {
return residents.size(); return residents != null ? residents.size() : 0;
} }
public class ResidentsViewHolder extends RecyclerView.ViewHolder { public class ResidentsViewHolder extends RecyclerView.ViewHolder {
@ -56,11 +54,12 @@ public class ResidentsAdapter extends RecyclerView.Adapter<ResidentsAdapter.Resi
public ResidentsViewHolder(View view) { public ResidentsViewHolder(View view) {
super(view); super(view);
residentName = view.findViewById(R.id.resident_name_item); residentName = view.findViewById(R.id.name_list_item);
} }
public void bindResident(Resident resident){ public void bindResident(Resident resident) {
residentName.setText(resident.getName()); String fullName = resident.getName() + " " + resident.getSurnames();
residentName.setText(fullName);
} }
} }
} }

View File

@ -0,0 +1,20 @@
package com.andresgmoran.apptrabajadores.models.gameStats;
public enum Difficulty {
FACIL,
MEDIO,
DIFICIL;
public static Difficulty fromString(String value) {
switch (value.toLowerCase()) {
case "facil":
return FACIL;
case "medio":
return MEDIO;
case "dificil":
return DIFICIL;
default:
throw new IllegalArgumentException("Valor de dificultad no válido: " + value);
}
}
}

View File

@ -0,0 +1,71 @@
package com.andresgmoran.apptrabajadores.models.gameStats;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Objects;
public class GameStat implements Serializable {
private final Long id;
private final Long residentId;
private final Long gameId;
private final Long userId;
private final Integer num;
private final Double duration;
private final Difficulty difficulty;
private final LocalDateTime dateTime;
public GameStat(Long id, Long residentId, Long gameId, Long userId, Integer num, Double duration, Difficulty difficulty, LocalDateTime dateTime) {
this.id = id;
this.residentId = residentId;
this.gameId = gameId;
this.userId = userId;
this.num = num;
this.duration = duration;
this.difficulty = difficulty;
this.dateTime = dateTime;
}
public Long getId() {
return id;
}
public Long getResidentId() {
return residentId;
}
public Long getGameId() {
return gameId;
}
public Long getUserId() {
return userId;
}
public Integer getNum() {
return num;
}
public Double getDuration() {
return duration;
}
public Difficulty getDifficulty() {
return difficulty;
}
public LocalDateTime getDateTime() {
return dateTime;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
GameStat gameStat = (GameStat) o;
return Objects.equals(id, gameStat.id) && Objects.equals(residentId, gameStat.residentId) && Objects.equals(gameId, gameStat.gameId) && Objects.equals(userId, gameStat.userId) && Objects.equals(num, gameStat.num) && Objects.equals(duration, gameStat.duration) && difficulty == gameStat.difficulty && Objects.equals(dateTime, gameStat.dateTime);
}
@Override
public int hashCode() {
return Objects.hash(id, residentId, gameId, userId, num, duration, difficulty, dateTime);
}
}

View File

@ -0,0 +1,37 @@
package com.andresgmoran.apptrabajadores.models.parsers;
import com.andresgmoran.apptrabajadores.models.Game;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class GameParser {
public static List<Game> parseGames(String jsonText) {
List<Game> games = new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(jsonText);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonGame = jsonArray.getJSONObject(i);
Long id = jsonGame.getLong("id");
String name = jsonGame.getString("nombre");
Long residenceId = jsonGame.getLong("idResidencia");
Game game = new Game(id, name, residenceId);
games.add(game);
}
} catch (JSONException e) {
e.printStackTrace(); //TODO: Throw personalized exception
}
return games;
}
}

View File

@ -0,0 +1,54 @@
package com.andresgmoran.apptrabajadores.models.parsers;
import com.andresgmoran.apptrabajadores.models.gameStats.Difficulty;
import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class GameStatParser {
public static List<GameStat> parseStats(String jsonText) {
List<GameStat> stats = new ArrayList<>();
try {
JSONArray array = new JSONArray(jsonText);
for (int i = 0; i < array.length(); i++) {
JSONObject obj = array.getJSONObject(i);
Long id = obj.getLong("id");
Long residentId = obj.getLong("idResidente");
Long gameId = obj.getLong("idJuego");
Long userId = obj.getLong("idUsario");
Integer num = obj.getInt("num");
Double duration = obj.getDouble("duracion");
Difficulty difficulty = null;
if (obj.has("dificultad") && !obj.isNull("dificultad")) {
String dificultadStr = obj.getString("dificultad").trim();
if (!dificultadStr.isEmpty()) {
difficulty = Difficulty.fromString(dificultadStr);
}
}
LocalDateTime dateTime = LocalDateTime.parse(
obj.getString("fecha"),
DateTimeFormatter.ISO_DATE_TIME // ejemplo: "2025-04-18T22:31:00"
);
stats.add(new GameStat(id, residentId, gameId, userId, num, duration, difficulty, dateTime));
}
} catch (JSONException e) {
e.printStackTrace();
}
return stats;
}
}

View File

@ -0,0 +1,41 @@
package com.andresgmoran.apptrabajadores.models.parsers;
import com.andresgmoran.apptrabajadores.models.Resident;
import org.json.JSONArray;
import org.json.JSONObject;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class ResidentParser {
public static List<Resident> parseResidents(String jsonText) {
List<Resident> residents = new ArrayList<>();
try {
JSONArray array = new JSONArray(jsonText);
for (int i = 0; i < array.length(); i++) {
JSONObject obj = array.getJSONObject(i);
Long id = obj.getLong("id");
String name = obj.getString("nombre");
String surnames = obj.getString("apellido");
// Convertir string a LocalDate (formato esperado: "2023-05-10")
String birthDateStr = obj.getString("fechaNacimiento");
LocalDate birthDate = LocalDate.parse(birthDateStr); // Usa formato ISO (yyyy-MM-dd)
Long residenceId = obj.getLong("idResidencia");
residents.add(new Resident(id, name, surnames, birthDate, residenceId));
}
} catch (Exception e) {
e.printStackTrace(); //TODO: Throw personalized exception
}
return residents;
}
}

View File

@ -0,0 +1,38 @@
package com.andresgmoran.apptrabajadores.models.parsers;
import com.andresgmoran.apptrabajadores.models.User;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class UserParser {
public static List<User> parseUsers(String jsonText) {
List<User> usuarios = new ArrayList<>();
try {
JSONArray array = new JSONArray(jsonText);
for (int i = 0; i < array.length(); i++) {
JSONObject obj = array.getJSONObject(i);
Long id = obj.getLong("id");
String name = obj.getString("nombre");
String surnames = obj.getString("apellido");
String email = obj.getString("email");
boolean enabled = obj.getBoolean("enabled");
Long residentId = obj.has("idResidencia") && !obj.isNull("residentId") ? obj.getLong("residentId") : null;
usuarios.add(new User(id, name, surnames, email, enabled, residentId));
}
} catch (Exception e) {
e.printStackTrace(); //TODO: Throw personalized exception
}
return usuarios;
}
}

View File

@ -0,0 +1,80 @@
package com.andresgmoran.apptrabajadores.network;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class ApiClient {
private static final String BASE_URL = "http://10.0.2.2:8080/resi/";
public interface RawCallback {
void onSuccess(String jsonText);
void onError(String error);
}
public static void getUsers(RawCallback callback) {
makeGetRequest("users", callback);
}
public static void getResidents(RawCallback callback) {
makeGetRequest("residents", callback);
}
public static void getGames(RawCallback callback) {
makeGetRequest("juegos", callback);
}
public static void getGamesStats(RawCallback callback) {
makeGetRequest("juegos/stats", callback);
}
private static void makeGetRequest(String endpoint, RawCallback callback) {
new Thread(() -> {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(BASE_URL + endpoint);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent", "Android");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder json = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
json.append(line);
}
// Devolver el JSON plano al hilo principal
new Handler(Looper.getMainLooper()).post(() ->
callback.onSuccess(json.toString()));
} else {
new Handler(Looper.getMainLooper()).post(() ->
callback.onError("Código de error: " + responseCode));
}
} catch (Exception e) {
Log.e("API", "Error: " + e.getMessage(), e);
new Handler(Looper.getMainLooper()).post(() ->
callback.onError("Excepción: " + e.getMessage()));
} finally {
try {
if (reader != null) reader.close();
if (connection != null) connection.disconnect();
} catch (Exception ignored) {}
}
}).start();
}
}

View File

@ -1,19 +1,32 @@
package com.andresgmoran.apptrabajadores.ui; package com.andresgmoran.apptrabajadores.ui;
import static java.lang.Thread.sleep;
import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import com.andresgmoran.apptrabajadores.R; import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.interfaces.IOChangeFragmentListener; import com.andresgmoran.apptrabajadores.interfaces.IOChangeFragmentListener;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnLatestGameListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameListener;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameStatsListener;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnResidentListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnResidentListener;
import com.andresgmoran.apptrabajadores.models.Contact;
import com.andresgmoran.apptrabajadores.models.Game; import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.LastGame;
import com.andresgmoran.apptrabajadores.models.Observation; import com.andresgmoran.apptrabajadores.models.Observation;
import com.andresgmoran.apptrabajadores.models.Resident; import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.Worker; import com.andresgmoran.apptrabajadores.models.User;
import com.andresgmoran.apptrabajadores.ui.fragments.GameDetailFragment; import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
import com.andresgmoran.apptrabajadores.models.parsers.GameParser;
import com.andresgmoran.apptrabajadores.models.parsers.GameStatParser;
import com.andresgmoran.apptrabajadores.models.parsers.ResidentParser;
import com.andresgmoran.apptrabajadores.models.parsers.UserParser;
import com.andresgmoran.apptrabajadores.network.ApiClient;
import com.andresgmoran.apptrabajadores.ui.fragments.game.GameFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.gameDetail.GameDetailFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.logIn.LoginFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.account.AccountFragment; import com.andresgmoran.apptrabajadores.ui.fragments.account.AccountFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.account.EditAccountFragment; import com.andresgmoran.apptrabajadores.ui.fragments.account.EditAccountFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.activities.ActivitiesFragment; import com.andresgmoran.apptrabajadores.ui.fragments.activities.ActivitiesFragment;
@ -24,36 +37,49 @@ import com.google.android.material.bottomnavigation.BottomNavigationView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.google.android.material.navigation.NavigationBarView; import com.google.android.material.navigation.NavigationBarView;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List; import java.util.List;
public class MainActivity extends AppCompatActivity implements NavigationBarView.OnItemSelectedListener, IOChangeFragmentListener, IOClickOnResidentListener, IOClickOnLatestGameListener, ResidentsListFragment.IOOnAttachListener,
GameDetailFragment.IOOnAttachListener, HomeFragment.IOOnAttachListenerResidents, HomeFragment.IOOnAttachListenerLatestsGames { public class MainActivity extends AppCompatActivity implements NavigationBarView.OnItemSelectedListener, LoginFragment.OnLoginListener, IOChangeFragmentListener, IOClickOnResidentListener, IOClickOnGameStatsListener, IOClickOnGameListener,
private List<Worker> workers; ResidentsListFragment.IOOnAttachListener, GameDetailFragment.IOOnAttachListener, HomeFragment.IOOnAttachListenerResidents, HomeFragment.IOOnAttachListenerGameStats, HomeFragment.IOOnAttachListenerGames {
private List<Resident> residents; private List<User> users = new ArrayList<>();
private List<Observation> observations; private List<Resident> residents = new ArrayList<>();
private List<Game> games; private final List<Observation> observations = new ArrayList<>();
private List<LastGame> lastsGames; private List<Game> games = new ArrayList<>();
private List<GameStat> gameStats = new ArrayList<>();
private String userLoggedEmail;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
createWorkers();
createResidents();
createObservations(); //Depende de workers
createGames(); //Depende de residents y workers
createLastGames(); //Depende de games y residents
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
// Adaptar diseño a la pantalla
View rootView = findViewById(R.id.fcvMain);
ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(0, systemBars.top, 0,0);
return insets;
});
SharedPreferences prefs = getSharedPreferences("session", MODE_PRIVATE);
userLoggedEmail = prefs.getString("email", null);
if (userLoggedEmail != null)
getResidentsFromAPI();
else
getUsersFromAPI();
BottomNavigationView navView = findViewById(R.id.nav_view); BottomNavigationView navView = findViewById(R.id.nav_view);
navView.setVisibility(View.GONE);
navView.setOnItemSelectedListener(this); navView.setOnItemSelectedListener(this);
} }
@ -62,7 +88,7 @@ GameDetailFragment.IOOnAttachListener, HomeFragment.IOOnAttachListenerResidents,
Fragment f = null; Fragment f = null;
int id = item.getItemId(); int id = item.getItemId();
if (id == R.id.navigation_home) if (id == R.id.navigation_home)
f = new HomeFragment(); f = createHomeFragment();
else if (id == R.id.navigation_list) else if (id == R.id.navigation_list)
f = new ResidentsListFragment(); f = new ResidentsListFragment();
else if (id == R.id.navigation_activities) else if (id == R.id.navigation_activities)
@ -72,7 +98,6 @@ GameDetailFragment.IOOnAttachListener, HomeFragment.IOOnAttachListenerResidents,
return loadFragment(f); return loadFragment(f);
} }
@Override @Override
public void changeFragment(String fragmentName) { public void changeFragment(String fragmentName) {
if(fragmentName.equals("AccountFragment")){ if(fragmentName.equals("AccountFragment")){
@ -91,30 +116,89 @@ GameDetailFragment.IOOnAttachListener, HomeFragment.IOOnAttachListenerResidents,
return false; return false;
} }
public List<Worker> createWorkers(){ public Fragment createHomeFragment(){
workers = new ArrayList<>(); HomeFragment homeFragment = new HomeFragment();
workers.add(new Worker("Pepe", "Motos", "Ocio")); Bundle bundle = new Bundle();
workers.add(new Worker("Juan", "Gonzalez", "Psicologo")); bundle.putString("email", userLoggedEmail);
workers.add(new Worker("Andres", "Gonzalez", "Psicologo")); bundle.putSerializable("users", (ArrayList<User>) users);
workers.add(new Worker("Luis", "Gonzalez", "Psicologo")); homeFragment.setArguments(bundle);
workers.add(new Worker("Carlos", "Gonzalez", "Psicologo")); return homeFragment;
return workers;
} }
@Override @Override
public List<Resident> getResidents() { public void onLoginSuccess(String email) {
BottomNavigationView navView = findViewById(R.id.nav_view);
ProgressBar loader = findViewById(R.id.progress_loader);
SharedPreferences prefs = getSharedPreferences("session", MODE_PRIVATE);
prefs.edit().putString("email", email).apply();
this.userLoggedEmail = email;
navView.setVisibility(View.GONE);
loader.setVisibility(View.VISIBLE);
getResidentsFromAPI();
}
/**
* Metodo para obtener los usuarios de la API
* @return
*/
public List<User> getUsersFromAPI(){
ApiClient.getUsers(new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
users = UserParser.parseUsers(jsonText);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fcvMain, new LoginFragment())
.commit();
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener usuarios: " + error);
}
});
return users;
}
@Override
public List<User> getUsers() {
return users;
}
/**
* Metodo para obtener los residentes de la API
* @return
*/
public List<Resident> getResidentsFromAPI(){
ApiClient.getResidents(new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
residents = ResidentParser.parseResidents(jsonText);
getGamesFromAPI();
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener residentes: " + error);
}
});
return residents; return residents;
} }
public List<Resident> createResidents(){
residents = new ArrayList<>(); /**
residents.add(new Resident("Andres", "Gonzalez", "17-09-2003")); * Metodo de los listeners de HomeFragment y ResidentListFragment para obtener los residentes
residents.add(new Resident("Juan", "Perez", "17-09-2003")); * @return
residents.add(new Resident("Pedro", "Gonzalez", "17-09-2003")); */
residents.add(new Resident("Maria", "Gonzalez", "17-09-2003")); @Override
residents.add(new Resident("Jose", "Gonzalez", "17-09-2003")); public List<Resident> getResidents() {
residents.add(new Resident("Luis", "Gonzalez", "17-09-2003"));
residents.add(new Resident("Carlos", "Gonzalez", "17-09-2003"));
residents.add(new Resident("Andres", "Gonzalez", "17-09-2003"));
return residents; return residents;
} }
@ -123,50 +207,100 @@ GameDetailFragment.IOOnAttachListener, HomeFragment.IOOnAttachListenerResidents,
return observations; return observations;
} }
public List<Observation> createObservations(){ public List<Observation> createObservations(){
observations = new ArrayList<>(); observations.add(new Observation(users.get(1), "El residente se encuentra en buen estado"));
observations.add(new Observation(workers.get(1), "El residente se encuentra en buen estado")); observations.add(new Observation(users.get(0), "El residente se encuentra en mal estado"));
observations.add(new Observation(workers.get(0), "El residente se encuentra en mal estado")); observations.add(new Observation(users.get(1), "El residente se encuentra en buen estado"));
observations.add(new Observation(workers.get(2), "El residente se encuentra en buen estado")); observations.add(new Observation(users.get(1), "El residente se encuentra en mal estado"));
observations.add(new Observation(workers.get(1), "El residente se encuentra en mal estado"));
return observations; return observations;
} }
public List<Game> createGames(){ public List<Game> getGamesFromAPI(){
games = new ArrayList<>(); ApiClient.getGames(new ApiClient.RawCallback() {
games.add(new Game("Follow the line", new Date(), new Date(), residents.get(1), workers.get(1))); @Override
games.add(new Game("Follow the line", new Date(), new Date(), residents.get(2), workers.get(1))); public void onSuccess(String jsonText) {
games.add(new Game("Follow the line", new Date(), new Date(), residents.get(3), workers.get(1))); games = GameParser.parseGames(jsonText);
games.add(new Game("Follow the line", new Date(), new Date(), residents.get(1), workers.get(1)));
getGameStatsFromAPI(); //Depende de games, residents y users
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener juegos: " + error);
}
});
return games; return games;
} }
@Override @Override
public List<LastGame> getLastestsGames() { public List<Game> getGames() {
return lastsGames; return games;
} }
public List<LastGame> createLastGames(){ public List<GameStat> getGameStatsFromAPI(){
lastsGames = new ArrayList<>(); ApiClient.getGamesStats(new ApiClient.RawCallback() {
lastsGames.add(new LastGame(residents.get(1), games.get(1), new Date())); @Override
lastsGames.add(new LastGame(residents.get(2), games.get(2), new Date())); public void onSuccess(String jsonText) {
lastsGames.add(new LastGame(residents.get(3), games.get(3), new Date())); gameStats = GameStatParser.parseStats(jsonText);
lastsGames.add(new LastGame(residents.get(4), games.get(1), new Date()));
return lastsGames; ProgressBar loader = findViewById(R.id.progress_loader);
BottomNavigationView navView = findViewById(R.id.nav_view);
runOnUiThread(() -> {
loader.setVisibility(View.GONE); // Ocultar loader
loadFragment(createHomeFragment());
navView.setVisibility(View.VISIBLE);
});
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener juegos: " + error);
}
});
return gameStats;
} }
@Override
public List<GameStat> getGameStats() {
return gameStats;
}
@Override @Override
public void onClickOnResident(Resident resident) { public void onClickOnResident(Resident resident) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putString("name", resident.getName()); bundle.putSerializable("resident", resident);
bundle.putFloatArray("data", new float[]{2.5f,5.8f,3.2f}); bundle.putSerializable("gameStats", (ArrayList<GameStat>) gameStats);
bundle.putSerializable("games", (ArrayList<Game>) games);
Fragment f = new ResidentFragment(); Fragment f = new ResidentFragment();
f.setArguments(bundle); f.setArguments(bundle);
loadFragment(f); loadFragment(f);
} }
@Override @Override
public void onClickOnLatestGame(LastGame game) { public void onClickOnLatestGame(GameStat gameStat, Resident gameStatResident, Game gameStatGame) {
loadFragment(new GameDetailFragment()); GameDetailFragment gameDetailFragment = new GameDetailFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("gameStat", gameStat);
bundle.putSerializable("gameStatResident", gameStatResident);
bundle.putSerializable("gameStatGame", gameStatGame);
gameDetailFragment.setArguments(bundle);
loadFragment(gameDetailFragment);
}
@Override
public void onClickOnGame(Game game) {
Bundle bundle = new Bundle();
bundle.putSerializable("game", game);
bundle.putSerializable("gameStats", (ArrayList<GameStat>) gameStats);
bundle.putSerializable("residents", (ArrayList<Resident>) residents);
Fragment f = new GameFragment();
f.setArguments(bundle);
loadFragment(f);
} }
} }

View File

@ -1,49 +0,0 @@
package com.andresgmoran.apptrabajadores.ui.fragments;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.models.Observation;
import com.andresgmoran.apptrabajadores.models.adapters.ObservationsAdapter;
import java.util.List;
public class GameDetailFragment extends Fragment {
public interface IOOnAttachListener{
List<Observation> getObservations();
}
List<Observation> observations;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate( R.layout.game_detail_fragment, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ObservationsAdapter observationsAdapter = new ObservationsAdapter(observations);
RecyclerView recyclerView = view.findViewById(R.id.observations_recycleView);
recyclerView.setAdapter( observationsAdapter );
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
GameDetailFragment.IOOnAttachListener attachListener = (GameDetailFragment.IOOnAttachListener) context;
observations = attachListener.getObservations();
}
}

View File

@ -21,7 +21,7 @@ public class AccountFragment extends Fragment {
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.account_fragment, container,false); return inflater.inflate(R.layout.fragment_account, container,false);
} }
@Override @Override

View File

@ -16,7 +16,7 @@ public class EditAccountFragment extends Fragment {
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.edit_account_fragment, container, false); return inflater.inflate(R.layout.fragment_edit_account, container, false);
} }
@Override @Override

View File

@ -16,7 +16,7 @@ public class ActivitiesFragment extends Fragment {
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate( R.layout.activities_fragment, container, false); return inflater.inflate( R.layout.fragment_activities_list, container, false);
} }
@Override @Override

View File

@ -0,0 +1,132 @@
package com.andresgmoran.apptrabajadores.ui.fragments.game;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameStatsListener;
import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.Observation;
import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.adapters.LastGamesAdapter;
import com.andresgmoran.apptrabajadores.models.adapters.ObservationsAdapter;
import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class GameFragment extends Fragment {
private List<GameStat> gameStats;
private List<Resident> residents;
private Game game;
private TextView gameNameTextView;
private TextView numberOfGamesLastWeekTextView;
private TextView totalGamesPlayedTextView;
private TextView topPlayerTextView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate( R.layout.fragment_game, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
gameNameTextView = view.findViewById(R.id.banner_name_game);
numberOfGamesLastWeekTextView = view.findViewById(R.id.tv_number_of_games_last_week);
totalGamesPlayedTextView = view.findViewById(R.id.tv_total_games_played);
topPlayerTextView = view.findViewById(R.id.tv_top_jugador);
List<GameStat> allGameStats = new ArrayList<>();
for (GameStat gs : gameStats){
if (gs.getGameId() == game.getId()){
allGameStats.add(gs);
}
}
gameNameTextView.setText(game.getName());
int numberOfGamesLastWeek = getGamesLastWeek(allGameStats);
numberOfGamesLastWeekTextView.setText(String.valueOf(numberOfGamesLastWeek));
totalGamesPlayedTextView.setText(String.valueOf(allGameStats.size()));
Resident topResident = getTopResident(allGameStats, residents);
if (topResident != null) {
topPlayerTextView.setText(topResident.getName());
} else {
topPlayerTextView.setText("No hay jugadores");
}
LastGamesAdapter lastGamesAdapter = new LastGamesAdapter(gameStats, game, residents, (IOClickOnGameStatsListener) requireActivity());
RecyclerView recyclerView = view.findViewById(R.id.rv_game_stats);
recyclerView.setAdapter( lastGamesAdapter );
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
}
private int getGamesLastWeek(List<GameStat> allGameStats) {
int count = 0;
LocalDateTime now = LocalDateTime.now();
LocalDateTime oneWeekAgo = now.minusDays(7);
for (GameStat gs : allGameStats) {
if (gs.getDateTime().isAfter(oneWeekAgo)) {
count++;
}
}
return count;
}
private Resident getTopResident(List<GameStat> allGameStats, List<Resident> residents) {
Resident topResident = null;
int maxGames = -1;
for (Resident resident : residents) {
int gamesCount = 0;
for (GameStat gs : allGameStats) {
if (gs.getResidentId() == resident.getId()) {
gamesCount++;
}
}
if (gamesCount > maxGames) {
maxGames = gamesCount;
topResident = resident;
}
}
return topResident;
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if(getArguments() != null) {
gameStats = (List<GameStat>) getArguments().getSerializable("gameStats");
residents = (List<Resident>) getArguments().getSerializable("residents");
game = (Game) getArguments().getSerializable("game");
}
}
}

View File

@ -0,0 +1,74 @@
package com.andresgmoran.apptrabajadores.ui.fragments.gameDetail;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.Observation;
import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.adapters.LastGamesAdapter;
import com.andresgmoran.apptrabajadores.models.adapters.ObservationsAdapter;
import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
import java.util.List;
public class GameDetailFragment extends Fragment {
public interface IOOnAttachListener{
List<Observation> getObservations();
}
private GameStat gameStat;
private Resident gameStatResident;
private Game gameStatGame;
private TextView residentNameTextView;
private TextView gameNameTextView;
private TextView durationTextView;
private TextView failsTextView;
List<Observation> observations;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate( R.layout.fragment_game_detail, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
residentNameTextView = view.findViewById(R.id.banner_name_resident);
gameNameTextView = view.findViewById(R.id.game_stats_detail_game_name);
durationTextView = view.findViewById(R.id.tv_duration);
failsTextView = view.findViewById(R.id.tv_fails);
residentNameTextView.setText(gameStatResident.getName() + " " + gameStatResident.getSurnames());
gameNameTextView.setText(gameStatGame.getName());
durationTextView.setText(Math.round(gameStat.getDuration()) + " seg");
failsTextView.setText(gameStat.getNum() + " fallos");
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if(getArguments() != null) {
gameStat = (GameStat) getArguments().getSerializable("gameStat");
gameStatResident = (Resident) getArguments().getSerializable("gameStatResident");
gameStatGame = (Game) getArguments().getSerializable("gameStatGame");
}
GameDetailFragment.IOOnAttachListener attachListener = (GameDetailFragment.IOOnAttachListener) context;
observations = attachListener.getObservations();
}
}

View File

@ -10,18 +10,20 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.andresgmoran.apptrabajadores.R; import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.databinding.FragmentHomeBinding; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameListener;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnLatestGameListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameStatsListener;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnResidentListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnResidentListener;
import com.andresgmoran.apptrabajadores.models.LastGame; import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.Resident; import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.User;
import com.andresgmoran.apptrabajadores.models.adapters.GamesAdapter;
import com.andresgmoran.apptrabajadores.models.adapters.LastGamesAdapter; import com.andresgmoran.apptrabajadores.models.adapters.LastGamesAdapter;
import com.andresgmoran.apptrabajadores.models.adapters.ResidentsAdapter; import com.andresgmoran.apptrabajadores.models.adapters.ResidentsAdapter;
import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
import java.util.List; import java.util.List;
@ -30,14 +32,24 @@ public class HomeFragment extends Fragment {
public interface IOOnAttachListenerResidents { public interface IOOnAttachListenerResidents {
List<Resident> getResidents(); List<Resident> getResidents();
} }
public interface IOOnAttachListenerLatestsGames { public interface IOOnAttachListenerGameStats {
List<LastGame> getLastestsGames(); List<GameStat> getGameStats();
} }
public interface IOOnAttachListenerGames {
List<Game> getGames();
}
private List<Resident> residents; private List<Resident> residents;
private List<LastGame> lastGames; private List<GameStat> gameStats;
private List<Game> games;
private List<User> users;
private String userEmail;
private TextView userNameTextView;
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false); return inflater.inflate(R.layout.fragment_home, container, false);
} }
@ -45,12 +57,27 @@ public class HomeFragment extends Fragment {
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
LastGamesAdapter lastGamesAdapter = new LastGamesAdapter(lastGames, (IOClickOnLatestGameListener) requireActivity()); userNameTextView = view.findViewById(R.id.home_user_name);
for (User user : users) {
if (user.getEmail().equals(userEmail)) {
String fullName = user.getName() + " " + user.getSurnames();
userNameTextView.setText(fullName);
break;
}
}
LastGamesAdapter lastGamesAdapter = new LastGamesAdapter(gameStats, games, residents, (IOClickOnGameStatsListener) requireActivity());
RecyclerView recyclerViewLastGames = view.findViewById(R.id.latestGames_recycleView_home); RecyclerView recyclerViewLastGames = view.findViewById(R.id.latestGames_recycleView_home);
recyclerViewLastGames.setAdapter(lastGamesAdapter); recyclerViewLastGames.setAdapter(lastGamesAdapter);
recyclerViewLastGames.setHasFixedSize(true); recyclerViewLastGames.setHasFixedSize(true);
recyclerViewLastGames.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false)); recyclerViewLastGames.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
GamesAdapter gamesAdapter = new GamesAdapter(games, (IOClickOnGameListener) requireActivity());
RecyclerView recyclerViewGames = view.findViewById(R.id.games_recycleView_home);
recyclerViewGames.setAdapter(gamesAdapter);
recyclerViewGames.setHasFixedSize(true);
recyclerViewGames.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
ResidentsAdapter adapter = new ResidentsAdapter(residents, (IOClickOnResidentListener) requireActivity()); ResidentsAdapter adapter = new ResidentsAdapter(residents, (IOClickOnResidentListener) requireActivity());
RecyclerView recyclerView = view.findViewById(R.id.residents_recycleView_home); RecyclerView recyclerView = view.findViewById(R.id.residents_recycleView_home);
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
@ -62,10 +89,18 @@ public class HomeFragment extends Fragment {
public void onAttach(@NonNull Context context) { public void onAttach(@NonNull Context context) {
super.onAttach(context); super.onAttach(context);
HomeFragment.IOOnAttachListenerLatestsGames attachListenerLastGames = (HomeFragment.IOOnAttachListenerLatestsGames) context; if (getArguments() != null) {
lastGames = attachListenerLastGames.getLastestsGames(); userEmail = getArguments().getString("email");
users = (List<User>) getArguments().getSerializable("users");
}
IOOnAttachListenerGameStats attachListenerLastGames = (IOOnAttachListenerGameStats) context;
gameStats = attachListenerLastGames.getGameStats();
HomeFragment.IOOnAttachListenerResidents attachListenerResidents = (HomeFragment.IOOnAttachListenerResidents) context; HomeFragment.IOOnAttachListenerResidents attachListenerResidents = (HomeFragment.IOOnAttachListenerResidents) context;
residents = attachListenerResidents.getResidents(); residents = attachListenerResidents.getResidents();
IOOnAttachListenerGames attachListenerGames = (IOOnAttachListenerGames) context;
games = attachListenerGames.getGames();
} }
} }

View File

@ -0,0 +1,85 @@
package com.andresgmoran.apptrabajadores.ui.fragments.logIn;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.models.User;
import java.util.List;
public class LoginFragment extends Fragment {
private OnLoginListener loginListener;
public interface OnLoginListener {
void onLoginSuccess(String email);
List<User> getUsers();
}
private EditText emailInput, passwordInput;
private Button loginButton;
private List<User> users;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_login, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
emailInput = view.findViewById(R.id.email_input);
passwordInput = view.findViewById(R.id.password_input);
loginButton = view.findViewById(R.id.login_button);
loginButton.setOnClickListener(v -> {
String email = emailInput.getText().toString().trim();
String password = passwordInput.getText().toString();
if (TextUtils.isEmpty(email) || TextUtils.isEmpty(password)) {
Toast.makeText(getActivity(), "Completa todos los campos", Toast.LENGTH_SHORT).show();
return;
}
for (User user : users) {
if (user.getEmail().equals(email)) {
loginListener.onLoginSuccess(email);
return;
}
}
Toast.makeText(getActivity(), "Usuario o contraseña incorrectos", Toast.LENGTH_SHORT).show();
});
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if (context instanceof OnLoginListener) {
users = ((OnLoginListener) context).getUsers();
} else {
throw new RuntimeException(context + " must implement OnLoginListener");
}
if (context instanceof OnLoginListener) {
loginListener = (OnLoginListener) context;
} else {
throw new RuntimeException(context.toString() + " must implement OnLoginListener");
}
}
}

View File

@ -6,57 +6,229 @@ import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.cardview.widget.CardView;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.andresgmoran.apptrabajadores.R; import com.andresgmoran.apptrabajadores.R;
import com.github.mikephil.charting.charts.LineChart; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameStatsListener;
import com.github.mikephil.charting.data.Entry; import com.andresgmoran.apptrabajadores.models.Game;
import com.github.mikephil.charting.data.LineData; import com.andresgmoran.apptrabajadores.models.Resident;
import com.github.mikephil.charting.data.LineDataSet; import com.andresgmoran.apptrabajadores.models.adapters.LastGamesAdapter;
import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
import com.andresgmoran.apptrabajadores.ui.graphics.CustomBarChartView;
import com.andresgmoran.apptrabajadores.ui.graphics.CustomPieChartView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class ResidentFragment extends Fragment { public class ResidentFragment extends Fragment {
private LineChart lineChart; private Resident resident;
private float[] chartData; private List<Game> games;
private List<GameStat> gameStats;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_resident, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
View banner = view.findViewById(R.id.resident_banner);
TextView residentName = banner.findViewById(R.id.banner_name_game);
String fullName = resident.getName() + " " + resident.getSurnames();
residentName.setText(fullName);
List<GameStat> filteredStats = new ArrayList<>();
for (GameStat stat : gameStats) {
if (Objects.equals(stat.getResidentId(), resident.getId())) {
filteredStats.add(stat);
}
}
LastGamesAdapter lastGamesAdapter = new LastGamesAdapter(filteredStats, games, resident, (IOClickOnGameStatsListener) requireActivity());
RecyclerView recyclerViewLastGames = view.findViewById(R.id.latestGames_recycleView_resident);
recyclerViewLastGames.setAdapter(lastGamesAdapter);
recyclerViewLastGames.setHasFixedSize(true);
recyclerViewLastGames.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
pieChart(view);
generateBarCharts(view);
}
private void pieChart(View view){
CustomPieChartView pieChart = view.findViewById(R.id.pieChart);
TextView[] gameNames = new TextView[]{
view.findViewById(R.id.pie_game_1_name),
view.findViewById(R.id.pie_game_2_name),
view.findViewById(R.id.pie_game_3_name),
view.findViewById(R.id.pie_game_4_name),
view.findViewById(R.id.pie_game_5_name)
};
Map<Long, Integer> gameCountMap = new HashMap<>();
for (GameStat stat : gameStats) {
if (Objects.equals(stat.getResidentId(), resident.getId())) {
Long gameId = stat.getGameId();
gameCountMap.put(gameId, gameCountMap.getOrDefault(gameId, 0) + 1);
}
}
int totalPartidas = gameCountMap.values().stream().mapToInt(Integer::intValue).sum();
float[] pieValues = new float[gameCountMap.size()];
int[] pieColors = new int[gameCountMap.size()];
int[] colorPool = { Color.YELLOW, Color.RED, Color.GREEN, Color.MAGENTA, Color.CYAN };
int index = 0;
for (Map.Entry<Long, Integer> entry : gameCountMap.entrySet()) {
float porcentaje = (entry.getValue() * 100f) / totalPartidas;
pieValues[index] = porcentaje;
pieColors[index] = colorPool[index % colorPool.length];
String nombreJuego = "";
for (Game g : games) {
if (g.getId().equals(entry.getKey())) {
nombreJuego = g.getName();
break;
}
}
if (index < gameNames.length) {
String texto = nombreJuego + " - " + String.format("%.1f", porcentaje) + "%";
gameNames[index].setText(texto);
gameNames[index].setVisibility(View.VISIBLE);
gameNames[index].setBackgroundColor(colorPool[index % colorPool.length]);
}
index++;
}
// Ocultar los TextView sobrantes si hay menos de 5 juegos
for (int i = index; i < gameNames.length; i++) {
gameNames[i].setVisibility(View.GONE);
}
pieChart.setData(pieValues, pieColors);
}
private void generateBarCharts(View view) {
LinearLayout barChartsContainer = view.findViewById(R.id.barChartsContainer);
barChartsContainer.removeAllViews();
Map<Long, Map<Integer, Integer>> juegosPorDias = new HashMap<>();
for (GameStat stat : gameStats) {
if (Objects.equals(stat.getResidentId(), resident.getId())) {
Long gameId = stat.getGameId();
int dia = stat.getDateTime().getDayOfWeek().getValue(); // 1 = lunes, ..., 7 = domingo
juegosPorDias
.computeIfAbsent(gameId, k -> new HashMap<>())
.put(dia, juegosPorDias.get(gameId).getOrDefault(dia, 0) + 1);
}
}
int index = 0;
LinearLayout currentRow = null;
for (Map.Entry<Long, Map<Integer, Integer>> entry : juegosPorDias.entrySet()) {
if (index >= 5) break;
if (index % 2 == 0) {
currentRow = new LinearLayout(requireContext());
currentRow.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams rowParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
rowParams.setMargins(0, 0, 0, 32);
currentRow.setLayoutParams(rowParams);
barChartsContainer.addView(currentRow);
}
String nombreJuego = "";
for (Game g : games) {
if (g.getId().equals(entry.getKey())) {
nombreJuego = g.getName();
break;
}
}
// Preparar datos por días de la semana
float[] datos = new float[7];
Map<Integer, Integer> actividadDias = entry.getValue();
for (int i = 1; i <= 7; i++) {
datos[i - 1] = actividadDias.getOrDefault(i, 0);
}
// Crear layout vertical del gráfico
LinearLayout chartLayout = new LinearLayout(requireContext());
chartLayout.setOrientation(LinearLayout.VERTICAL);
chartLayout.setPadding(16, 16, 16, 16);
TextView title = new TextView(requireContext());
title.setText(nombreJuego);
title.setTextColor(Color.BLACK);
title.setTextSize(14);
chartLayout.addView(title);
TextView subtitle = new TextView(requireContext());
subtitle.setText("Actividad semanal");
subtitle.setTextColor(Color.GRAY);
subtitle.setTextSize(12);
chartLayout.addView(subtitle);
CustomBarChartView chart = new CustomBarChartView(requireContext(), null);
chart.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
500
));
chart.setData(datos);
chartLayout.addView(chart);
CardView cardView = new CardView(requireContext());
cardView.setCardElevation(6f);
cardView.setRadius(32f); // 16dp
cardView.setUseCompatPadding(true);
cardView.setCardBackgroundColor(Color.WHITE);
cardView.addView(chartLayout);
LinearLayout.LayoutParams colParams = new LinearLayout.LayoutParams(
0,
ViewGroup.LayoutParams.WRAP_CONTENT,
1f
);
colParams.setMargins(8, 0, 8, 0);
cardView.setLayoutParams(colParams);
currentRow.addView(cardView);
index++;
}
}
@Override @Override
public void onAttach(@NonNull Context context) { public void onAttach(@NonNull Context context) {
super.onAttach(context); super.onAttach(context);
Bundle args = getArguments(); Bundle args = getArguments();
if (args != null) { if (args != null) {
chartData = args.getFloatArray("data"); resident = (Resident) args.getSerializable("resident");
games = (ArrayList<Game>) args.getSerializable("games");
gameStats = (ArrayList<GameStat>) args.getSerializable("gameStats");
} }
} }
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.resident_fragment, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
lineChart = view.findViewById(R.id.lineChart);
updateChart(chartData);
}
public void updateChart(float[] data) {
ArrayList<Entry> entries = new ArrayList<>();
for (int i = 0; i < data.length; i++) {
entries.add(new Entry(i, data[i]));
}
LineDataSet dataSet = new LineDataSet(entries, "Datos");
dataSet.setColor(Color.BLUE);
dataSet.setValueTextColor(Color.BLACK);
dataSet.setLineWidth(2f);
dataSet.setCircleRadius(4f);
dataSet.setDrawCircles(true);
LineData lineData = new LineData(dataSet);
lineChart.setData(lineData);
lineChart.invalidate(); // Refresca el gráfico
}
} }

View File

@ -29,7 +29,7 @@ public class ResidentsListFragment extends Fragment {
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate( R.layout.residents_list_fragment, container, false); return inflater.inflate( R.layout.fragment_residents_list, container, false);
} }
@Override @Override

View File

@ -0,0 +1,75 @@
package com.andresgmoran.apptrabajadores.ui.graphics;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class CustomBarChartView extends View {
private Paint paint;
private Paint textPaint;
private float[] data = {};
private boolean hasData = false;
private final String[] diasSemana = {"L", "M", "X", "J", "V", "S", "D"};
public CustomBarChartView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.parseColor("#4285F4"));
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(Color.BLACK);
textPaint.setTextSize(30f);
textPaint.setTextAlign(Paint.Align.CENTER);
}
public void setData(float[] data) {
this.data = data;
hasData = true;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!hasData || data.length == 0) return;
int width = getWidth();
int height = getHeight();
int marginBottom = 60;
int marginTop = 30;
int availableHeight = height - marginBottom - marginTop;
int barWidth = width / (data.length * 2);
// Escala máxima
float maxVal = 0f;
for (float val : data) maxVal = Math.max(maxVal, val);
if (maxVal == 0f) maxVal = 1f;
for (int i = 0; i < data.length; i++) {
float left = i * 2 * barWidth + barWidth / 2f;
float barHeight = (data[i] / maxVal) * availableHeight;
float top = height - marginBottom - barHeight;
float right = left + barWidth;
float bottom = height - marginBottom;
canvas.drawRoundRect(left, top, right, bottom, 20f, 20f, paint);
float centerX = (left + right) / 2f;
canvas.drawText(diasSemana[i], centerX, height - 20, textPaint);
}
}
}

View File

@ -0,0 +1,60 @@
package com.andresgmoran.apptrabajadores.ui.graphics;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
public class CustomPieChartView extends View {
private Paint paint;
private RectF rect;
private float[] values = {};
private int[] colors = {};
private boolean hasData = false;
public CustomPieChartView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
rect = new RectF();
}
public void setData(float[] values, int[] colors) {
this.values = values;
this.colors = colors;
hasData = true;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!hasData || values.length == 0 || colors.length != values.length) return;
float total = 0;
for (float val : values) total += val;
float startAngle = -90f;
int size = Math.min(getWidth(), getHeight());
float padding = 40;
rect.set(padding, padding, size - padding, size - padding);
for (int i = 0; i < values.length; i++) {
float sweepAngle = (values[i] / total) * 360f;
paint.setColor(colors[i]);
canvas.drawArc(rect, startAngle, sweepAngle, true, paint);
startAngle += sweepAngle;
}
paint.setColor(Color.WHITE);
canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, size / 4f, paint);
}
}

View File

@ -0,0 +1,4 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#6CADFF" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
app:fontProviderAuthority="com.google.android.gms.fonts"
app:fontProviderPackage="com.google.android.gms"
app:fontProviderQuery="Assistant:wght600"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>

View File

@ -1,28 +1,48 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container" android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:paddingTop="?attr/actionBarSize">
<!-- Incluye el contenido principal respetando el BottomNav -->
<include <include
android:id="@+id/content_main_include"
layout="@layout/content_main" layout="@layout/content_main"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="match_parent"/> android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/nav_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- Círculo de carga centrado -->
<ProgressBar
android:id="@+id/progress_loader"
style="?android:attr/progressBarStyleLarge"
android:layout_width="80dp"
android:layout_height="80dp"
android:visibility="gone"
android:layout_margin="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!-- Menú de navegación inferior anclado abajo -->
<com.google.android.material.bottomnavigation.BottomNavigationView <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view" android:id="@+id/nav_view"
style="@style/RoundedBottomNav" style="@style/RoundedBottomNav"
android:layout_width="0dp" android:layout_width="407dp"
android:layout_height="wrap_content" android:layout_height="56dp"
android:background="?android:attr/windowBackground"
android:layout_marginHorizontal="30dp" android:layout_marginHorizontal="30dp"
android:layout_marginVertical="40dp" android:layout_marginBottom="40dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_nav_menu" /> app:menu="@menu/bottom_nav_menu" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -2,11 +2,11 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:background="#CCCCCC">
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView
android:id="@+id/fcvMain" android:id="@+id/fcvMain"
android:name="com.andresgmoran.apptrabajadores.ui.fragments.home.HomeFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"

View File

@ -8,7 +8,7 @@
<include <include
android:id="@+id/include" android:id="@+id/include"
layout="@layout/person_banner" layout="@layout/item_person_banner"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -76,7 +76,7 @@
<include <include
android:id="@+id/include" android:id="@+id/include"
layout="@layout/person_banner" layout="@layout/item_person_banner"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View File

@ -0,0 +1,188 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:background="#CCCCCC">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Banner azul -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/background_banner"
android:layout_width="0dp"
android:layout_height="174dp"
android:background="#0062FF"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<!-- Botón superior izquierdo -->
<ImageButton
android:id="@+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@null"
app:srcCompat="@drawable/arrow_left"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<!-- Avatar + texto -->
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/circularImageView"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginStart="20dp"
android:layout_marginTop="16dp"
android:scaleType="centerCrop"
android:src="@drawable/woman_avatar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/imageButton2"
app:shapeAppearanceOverlay="@style/CircularShapeAppearance" />
<TextView
android:id="@+id/banner_name_game"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="33dp"
android:fontFamily="@font/assistant_bold"
android:textColor="@android:color/white"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="@+id/circularImageView"
app:layout_constraintStart_toEndOf="@+id/circularImageView"
app:layout_constraintTop_toTopOf="@+id/circularImageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Título Información -->
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:fontFamily="@font/assistant_semibold"
android:gravity="center"
android:text="Información"
android:textColor="#324F5E"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/background_banner" />
<!-- Contenedor de duración y fallos -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/stats_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#CCCCCC"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView2">
<!-- Duración -->
<TextView
android:id="@+id/label_number_of_games_last_week"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="@font/assistant_semibold"
android:text="Partidas úlrima semana"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toStartOf="@+id/tv_number_of_games_last_week"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_number_of_games_last_week"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/assistant_semibold"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/label_number_of_games_last_week" />
<!-- Fallos -->
<TextView
android:id="@+id/label_total_games_played"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/assistant_semibold"
android:text="Partidas jugadas"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toStartOf="@id/tv_total_games_played"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/label_number_of_games_last_week" />
<TextView
android:id="@+id/tv_total_games_played"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/assistant_semibold"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/label_total_games_played" />
<TextView
android:id="@+id/label_top_jugador"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/assistant_semibold"
android:text="Top jugador"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toStartOf="@id/tv_total_games_played"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/label_total_games_played" />
<TextView
android:id="@+id/tv_top_jugador"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/assistant_semibold"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/label_top_jugador" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/textView6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="#FFFFFFFF"
android:fontFamily="@font/assistant_semibold"
android:gravity="center"
android:text="Partidas"
android:textColor="#324F5E"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stats_container" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_game_stats"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:nestedScrollingEnabled="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView6" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:background="#CCCCCC">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Banner azul -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/background_banner"
android:layout_width="0dp"
android:layout_height="174dp"
android:background="#0062FF"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<!-- Botón superior izquierdo -->
<ImageButton
android:id="@+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@null"
app:srcCompat="@drawable/arrow_left"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<!-- Avatar + texto -->
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/circularImageView"
android:layout_width="80dp"
android:layout_height="80dp"
android:scaleType="centerCrop"
android:src="@drawable/woman_avatar"
app:shapeAppearanceOverlay="@style/CircularShapeAppearance"
app:layout_constraintTop_toBottomOf="@id/imageButton2"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="16dp"
android:layout_marginStart="20dp" />
<LinearLayout
android:id="@+id/user_info"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="@id/circularImageView"
app:layout_constraintBottom_toBottomOf="@id/circularImageView"
app:layout_constraintStart_toEndOf="@id/circularImageView"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp">
<TextView
android:id="@+id/banner_name_resident"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/assistant_bold"
android:textColor="@android:color/white"
android:textSize="24sp" />
<TextView
android:id="@+id/game_stats_detail_game_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/assistant_semibold"
android:textColor="@android:color/white" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Título Información -->
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:fontFamily="@font/assistant_semibold"
android:gravity="center"
android:text="Información"
android:textColor="#324F5E"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/background_banner" />
<!-- Contenedor de duración y fallos -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/stats_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#CCCCCC"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView2">
<!-- Duración -->
<TextView
android:id="@+id/label_duration"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="@font/assistant_semibold"
android:text="Duración"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toStartOf="@+id/tv_duration"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/assistant_semibold"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/label_duration" />
<!-- Fallos -->
<TextView
android:id="@+id/label_fails"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/assistant_semibold"
android:text="Fallos"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toStartOf="@id/tv_fails"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/label_duration" />
<TextView
android:id="@+id/tv_fails"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/assistant_semibold"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/label_fails" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Observaciones -->
<TextView
android:id="@+id/textView6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="#FFFFFFFF"
android:fontFamily="@font/assistant_semibold"
android:gravity="center"
android:text="Observaciones"
android:textColor="#324F5E"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stats_container" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/last_games_recycleView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:nestedScrollingEnabled="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView6" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -30,23 +30,29 @@
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:id="@+id/observation_person_name" android:id="@+id/home_user_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="5dp" android:layout_marginStart="5dp"
android:text="Maria Cartes Sanchez" /> android:fontFamily="@font/assistant_bold"
android:text="Maria Cartes Sanchez"
android:textColor="#324F5E"
android:textSize="24sp" />
<TextView <TextView
android:id="@+id/observation_person_role" android:id="@+id/observation_person_role"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="5dp" android:layout_marginStart="5dp"
android:text="Psicologa" /> android:fontFamily="@font/assistant_semibold"
android:text="Psicologa"
android:textColor="#96A7AF"
android:textSize="16sp" />
</LinearLayout> </LinearLayout>
<com.google.android.material.imageview.ShapeableImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/circularImageView3" android:id="@+id/circularImageView3"
android:layout_width="52dp" android:layout_width="55dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerCrop" android:scaleType="centerCrop"
app:shapeAppearanceOverlay="@style/CircularShapeAppearance" app:shapeAppearanceOverlay="@style/CircularShapeAppearance"
@ -57,8 +63,8 @@
android:id="@+id/linearLayout2" android:id="@+id/linearLayout2"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" android:layout_marginHorizontal="20dp"
android:layout_marginTop="20dp" android:layout_marginTop="30dp"
android:orientation="horizontal" android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -69,15 +75,21 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:text="Últimas partidas" /> android:fontFamily="@font/assistant_bold"
android:text="Últimas partidas"
android:textColor="#324F5E"
android:textSize="20sp" />
<TextView <TextView
android:id="@+id/textView17" android:id="@+id/textView17"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:gravity="center" android:fontFamily="@font/assistant_semibold"
android:text="Ver más" /> android:gravity="right"
android:text="Ver más"
android:textColor="#0062FF"
android:textSize="14sp" />
</LinearLayout> </LinearLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
@ -85,35 +97,85 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:nestedScrollingEnabled="false"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/linearLayout2" app:layout_constraintTop_toBottomOf="@id/linearLayout2" />
android:nestedScrollingEnabled="false" />
<LinearLayout <LinearLayout
android:id="@+id/linearLayout3" android:id="@+id/linearLayout4"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" android:layout_marginHorizontal="20dp"
android:layout_marginTop="20dp"
android:orientation="horizontal" android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/latestGames_recycleView_home"> app:layout_constraintTop_toBottomOf="@id/latestGames_recycleView_home">
<TextView
android:id="@+id/textView18"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Residentes" />
<TextView <TextView
android:id="@+id/textView19" android:id="@+id/textView19"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:gravity="center" android:fontFamily="@font/assistant_bold"
android:text="Ver más" /> android:text="Juegos"
android:textColor="#324F5E"
android:textSize="20sp" />
<ImageButton
android:id="@+id/filter_games_list_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:contentDescription="Filtro"
app:srcCompat="@drawable/filter" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/games_recycleView_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:nestedScrollingEnabled="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/linearLayout4" />
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="20dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/games_recycleView_home">
<TextView
android:id="@+id/textView18"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="@font/assistant_bold"
android:text="Residentes"
android:textColor="#324F5E"
android:textSize="20sp" />
<ImageButton
android:id="@+id/filter_residents_list_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:contentDescription="Filtro"
app:srcCompat="@drawable/filter" />
</LinearLayout> </LinearLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
@ -121,10 +183,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:nestedScrollingEnabled="false"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/linearLayout3" app:layout_constraintTop_toBottomOf="@id/linearLayout3" />
android:nestedScrollingEnabled="false" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp">
<TextView
android:id="@+id/login_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:fontFamily="@font/assistant_bold"
android:text="Iniciar Sesión"
android:textColor="#324F5E"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/email_input"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/email_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:hint="Correo electrónico"
android:inputType="textEmailAddress"
android:textColorLink="#324F5E"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/login_title" />
<EditText
android:id="@+id/password_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:hint="Contraseña"
android:inputType="textPassword"
android:textColorLink="#324F5E"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/email_input" />
<Button
android:id="@+id/login_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Iniciar sesión"
android:backgroundTint="#324F5E"
app:layout_constraintTop_toBottomOf="@id/password_input"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCCCCC"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/resident_scroll_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Banner superior -->
<include
android:id="@+id/resident_banner"
layout="@layout/item_person_banner"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="20dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/resident_banner">
<TextView
android:id="@+id/textView15"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="@font/assistant_bold"
android:text="Últimas partidas"
android:textColor="#324F5E"
android:textSize="20sp" />
<TextView
android:id="@+id/textView17"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="@font/assistant_semibold"
android:gravity="right"
android:text="Ver más"
android:textColor="#0062FF" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/latestGames_recycleView_resident"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:nestedScrollingEnabled="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/linearLayout2" />
<TextView
android:id="@+id/textView16"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="20dp"
android:fontFamily="@font/assistant_bold"
android:text="Estadísticas"
android:textColor="#324F5E"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/latestGames_recycleView_resident" />
<!-- Card con gráfico de dona -->
<androidx.cardview.widget.CardView
android:id="@+id/pieCard"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_marginTop="20dp"
app:cardCornerRadius="16dp"
app:cardElevation="6dp"
app:layout_constraintTop_toBottomOf="@+id/textView16"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:padding="16dp">
<com.andresgmoran.apptrabajadores.ui.graphics.CustomPieChartView
android:id="@+id/pieChart"
android:layout_width="150dp"
android:layout_height="150dp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:paddingStart="16dp">
<TextView
android:id="@+id/pie_game_1_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:background="#FFFF00"
android:text="Sombras - 45%"
android:textColor="#000000" />
<TextView
android:id="@+id/pie_game_2_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:background="#FF6666"
android:text="Reacción auditiva - 30%"
android:textColor="#000000" />
<TextView
android:id="@+id/pie_game_3_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:background="#FF00FF"
android:text="Memoria - 15%"
android:textColor="#000000" />
<TextView
android:id="@+id/pie_game_4_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:background="#00FF00"
android:text="Laberinto - 10%"
android:textColor="#000000" />
<TextView android:id="@+id/pie_game_5_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#00FF00" android:text="Laberinto - 10%" android:textColor="#000000"/>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Contenedor de gráficos de barras -->
<LinearLayout
android:id="@+id/barChartsContainer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:layout_margin="16dp"
app:layout_constraintTop_toBottomOf="@id/pieCard"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCCCCC">
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/latestGames_recycleView_home">
<TextView
android:id="@+id/textView18"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="@font/assistant_bold"
android:text="Residentes"
android:textColor="#324F5E"
android:textSize="20sp" />
<ImageButton
android:id="@+id/filter_residents_list_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:contentDescription="Filtro"
app:srcCompat="@drawable/filter" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/residents_recycleView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="@+id/linearLayout3"
app:layout_constraintStart_toStartOf="@+id/linearLayout3"
app:layout_constraintTop_toBottomOf="@+id/linearLayout3" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,173 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:background="#CCCCCC">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ScrollView
android:id="@+id/background_banner"
android:layout_width="0dp"
android:layout_height="174dp"
android:background="#0062FF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ScrollView
android:id="@+id/top_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="@+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:layout_weight="1"
app:srcCompat="@android:drawable/ic_media_previous" />
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp"
android:orientation="horizontal">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/circularImageView"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerInParent="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="0dp"
android:scaleType="centerCrop"
android:src="@drawable/woman_avatar"
app:shapeAppearanceOverlay="@style/CircularShapeAppearance" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:fontFamily="@font/assistant_bold"
android:text="Jose Manuel Carrasco"
android:textSize="24sp" />
<TextView
android:id="@+id/textView16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Sigue la linea" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="20dp"
android:background="#FFFF"
android:fontFamily="@font/assistant_bold"
android:paddingStart="20dp"
android:text="Información"
android:textColor="#324F5E"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/background_banner" />
<TextView
android:id="@+id/textView3"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_marginTop="5dp"
android:fontFamily="@font/assistant_bold"
android:paddingStart="20dp"
android:text="Tiempo"
android:textColor="#324F5E"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" />
<TextView
android:id="@+id/textView4"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_marginTop="5dp"
android:fontFamily="@font/assistant_bold"
android:paddingStart="20dp"
android:text="Fallos"
android:textColor="#324F5E"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView3" />
<TextView
android:id="@+id/textView5"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_marginTop="5dp"
android:fontFamily="@font/assistant_bold"
android:paddingStart="20dp"
android:text="Aciertos"
android:textColor="#324F5E"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView4" />
<TextView
android:id="@+id/textView6"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_marginTop="10dp"
android:background="#FFFFFFFF"
android:fontFamily="@font/assistant_bold"
android:paddingStart="20dp"
android:text="Observaciones"
android:textColor="#324F5E"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView5" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/observations_recycleView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView6" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardCornerRadius="16dp"
app:cardElevation="4dp"
android:background="@color/black">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0062FF"
android:padding="16dp">
<TextView
android:id="@+id/textview_salida"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Salida"
android:textColor="@android:color/white"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/name_salida"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/assistant_bold"
android:text="Iglesia de Benissa"
android:textColor="#F4F4F4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textview_salida" />
<ImageView
android:id="@+id/more_options_activityItem"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/woman_avatar"
android:tint="#FFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/date_text_activityItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="Lunes, 17 de marzo 2025"
android:textColor="@android:color/white"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/name_salida" />
<TextView
android:id="@+id/time_text_activityItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="10:00am"
android:textColor="@android:color/white"
android:textSize="14sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/date_text_activityItem" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

View File

@ -31,7 +31,7 @@
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:id="@+id/resident_name_item" android:id="@+id/name_list_item"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Resident Name" android:text="Resident Name"

View File

@ -28,7 +28,7 @@
android:layout_marginStart="10dp"> android:layout_marginStart="10dp">
<TextView <TextView
android:id="@+id/observation_person_name" android:id="@+id/home_user_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Person Name" android:text="Person Name"

View File

@ -34,21 +34,15 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
app:srcCompat="@android:drawable/ic_media_previous" android:background="@android:color/transparent"
app:srcCompat="@drawable/arrow_left"
android:layout_marginStart="2dp"/> android:layout_marginStart="2dp"/>
<ImageButton
android:id="@+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="300dp"
android:layout_weight="1"
app:srcCompat="@android:drawable/ic_popup_reminder" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
<TextView <TextView
android:id="@+id/textView" android:id="@+id/banner_name_game"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="4dp"
android:layout_margin="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp">
<!-- Imagen circular -->
<ImageView
android:id="@+id/profile_image"
android:layout_width="40dp"
android:layout_height="40dp"
android:scaleType="centerInside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<!-- Nombre -->
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Jose Manuel Carrasco"
android:textColor="#324F5E"
android:textStyle="bold"
android:textSize="16sp"
android:layout_marginStart="12dp"
app:layout_constraintStart_toEndOf="@id/profile_image"
app:layout_constraintTop_toTopOf="@id/profile_image"
app:layout_constraintEnd_toEndOf="parent"/>
<!-- Primer botón -->
<ImageButton
android:id="@+id/btn_first"
android:layout_width="48dp"
android:layout_height="48dp"
android:backgroundTint="#6CADFF"
android:src="@drawable/logo_confirmation"
android:background="@drawable/activity_button_unpressed_background"
android:scaleType="centerInside"
android:padding="8dp"
app:layout_constraintTop_toBottomOf="@id/tv_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_second"
android:layout_marginTop="12dp"/>
<!-- Segundo botón -->
<ImageButton
android:id="@+id/btn_second"
android:layout_width="48dp"
android:layout_height="48dp"
android:backgroundTint="#6CADFF"
android:src="@drawable/logo_text"
android:background="@drawable/activity_button_unpressed_background"
android:scaleType="centerInside"
android:padding="8dp"
app:layout_constraintTop_toBottomOf="@id/tv_name"
app:layout_constraintStart_toEndOf="@id/btn_first"
app:layout_constraintEnd_toStartOf="@id/btn_third"
android:layout_marginStart="8dp"
android:layout_marginTop="12dp"/>
<!-- Tercer botón -->
<ImageButton
android:id="@+id/btn_third"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/activity_button_unpressed_background"
android:src="@drawable/logo_help"
app:shapeAppearanceOverlay="@style/CircularShapeAppearance"
android:scaleType="centerInside"
android:padding="8dp"
app:layout_constraintTop_toBottomOf="@id/tv_name"
app:layout_constraintStart_toEndOf="@id/btn_second"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginStart="8dp"
android:layout_marginTop="12dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

View File

@ -1,13 +0,0 @@
<?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="match_parent"
android:orientation="vertical"
android:padding="16dp">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/lineChart"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCCCCC">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/residents_recycleView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -8,23 +8,23 @@
<fragment <fragment
android:id="@+id/navigation_home" android:id="@+id/navigation_home"
android:name="com.andresgmoran.apptrabajadores.ui.fragments.account.AccountFragment" android:name="com.andresgmoran.apptrabajadores.ui.fragments.account.AccountFragment"
tools:layout="@layout/account_fragment" /> tools:layout="@layout/fragment_account" />
<fragment <fragment
android:id="@+id/lista" android:id="@+id/lista"
android:name="com.andresgmoran.apptrabajadores.ui.fragments.residentList.ResidentsListFragment" android:name="com.andresgmoran.apptrabajadores.ui.fragments.residentList.ResidentsListFragment"
android:label="@string/title_dashboard" android:label="@string/title_dashboard"
tools:layout="@layout/residents_list_fragment" /> tools:layout="@layout/fragment_residents_list" />
<fragment <fragment
android:id="@+id/activities" android:id="@+id/activities"
android:name="com.andresgmoran.apptrabajadores.ui.fragments.activities.ActivitiesFragment" android:name="com.andresgmoran.apptrabajadores.ui.fragments.activities.ActivitiesFragment"
android:label="@string/title_notifications" android:label="@string/title_notifications"
tools:layout="@layout/activities_fragment" /> tools:layout="@layout/fragment_activities_list" />
<fragment <fragment
android:id="@+id/account" android:id="@+id/account"
android:name="com.andresgmoran.apptrabajadores.ui.fragments.account.AccountFragment" android:name="com.andresgmoran.apptrabajadores.ui.fragments.account.AccountFragment"
android:label="Account" android:label="Account"
tools:layout="@layout/account_fragment" /> tools:layout="@layout/fragment_account" />
</navigation> </navigation>

View File

@ -2,5 +2,6 @@
<resources> <resources>
<array name="preloaded_fonts" translatable="false"> <array name="preloaded_fonts" translatable="false">
<item>@font/assistant_bold</item> <item>@font/assistant_bold</item>
<item>@font/assistant_semibold</item>
</array> </array>
</resources> </resources>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
</domain-config>
</network-security-config>

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -8,7 +8,7 @@ Anim={
"grid_snap_active": false, "grid_snap_active": false,
"grid_step": Vector2(8, 8), "grid_step": Vector2(8, 8),
"grid_visibility": 1, "grid_visibility": 1,
"ofs": Vector2(-852.9, -156.826), "ofs": Vector2(-851.476, -324.925),
"primary_grid_step": Vector2i(8, 8), "primary_grid_step": Vector2i(8, 8),
"show_group_gizmos": true, "show_group_gizmos": true,
"show_guides": true, "show_guides": true,

View File

@ -1,5 +1,5 @@
[folding] [folding]
node_unfolds=[NodePath("Window/ColorRect"), PackedStringArray("Layout"), NodePath("Window/VBoxContainer"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/constants", "Layout/Transform"), NodePath("Window/VBoxContainer/Label"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/colors"), NodePath("Window/VBoxContainer/EmailInput"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal"), NodePath("Window/VBoxContainer/Label2"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/colors"), NodePath("Window/VBoxContainer/PasswordInput"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal"), NodePath("Window/VBoxContainer/LogInButton"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal"), NodePath("Bloqueador"), PackedStringArray("Visibility", "Layout", "Mouse")] node_unfolds=[NodePath("."), PackedStringArray("Layout"), NodePath("MarginContainer"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/constants"), NodePath("MarginContainer/VBoxContainer"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/constants"), NodePath("MarginContainer/VBoxContainer/Label"), PackedStringArray("Theme Overrides", "Theme Overrides/font_sizes", "Theme Overrides/colors"), NodePath("MarginContainer/VBoxContainer/Label2"), PackedStringArray("Theme Overrides", "Theme Overrides/font_sizes", "Theme Overrides/colors"), NodePath("MarginContainer/VBoxContainer/MenuButton"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "theme_override_styles/normal", "Theme Overrides/colors"), NodePath("MarginContainer/VBoxContainer/Label3"), PackedStringArray("Theme Overrides", "Theme Overrides/font_sizes", "Layout", "Theme Overrides/colors"), NodePath("MarginContainer/VBoxContainer/PlayButton"), PackedStringArray("Theme Overrides", "Layout", "Layout/Container Sizing", "Theme Overrides/styles", "theme_override_styles/normal"), NodePath("Bloqueador"), PackedStringArray("Visibility", "Layout", "Mouse"), NodePath("Warning"), PackedStringArray("Flags"), NodePath("Warning/Panel"), PackedStringArray("Theme Overrides", "Layout", "Theme Overrides/styles", "theme_override_styles/panel"), NodePath("Window/ColorRect"), PackedStringArray("Layout"), NodePath("Window/VBoxContainer"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/constants", "Layout/Transform"), NodePath("Window/VBoxContainer/Label"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/colors"), NodePath("Window/VBoxContainer/EmailInput"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal"), NodePath("Window/VBoxContainer/Label2"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/colors"), NodePath("Window/VBoxContainer/PasswordInput"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal"), NodePath("Window/VBoxContainer/LogInButton"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal")]
resource_unfolds=["res://scenes/configuration.tscn::StyleBoxFlat_hc4xr", PackedStringArray(), "res://scenes/configuration.tscn::StyleBoxFlat_7wcdq", PackedStringArray(), "res://scenes/configuration.tscn::StyleBoxFlat_lditi", PackedStringArray()] resource_unfolds=["res://scenes/configuration.tscn::StyleBoxFlat_kporg", PackedStringArray(), "res://scenes/configuration.tscn::StyleBoxFlat_etp6l", PackedStringArray(), "res://scenes/configuration.tscn::StyleBoxFlat_sb302", PackedStringArray(), "res://scenes/configuration.tscn::StyleBoxFlat_hc4xr", PackedStringArray(), "res://scenes/configuration.tscn::StyleBoxFlat_7wcdq", PackedStringArray(), "res://scenes/configuration.tscn::StyleBoxFlat_lditi", PackedStringArray()]
nodes_folded=[NodePath("VBoxContainer")] nodes_folded=[NodePath("MarginContainer"), NodePath("MarginContainer/VBoxContainer"), NodePath("Warning"), NodePath("Window")]

View File

@ -1,14 +1,14 @@
ColorRect ColorRect
Control CenterContainer
VBoxContainer
Button Button
LineEdit
Label
Window
MenuButton
HBoxContainer HBoxContainer
FlowContainer Label
VBoxContainer
Window
MarginContainer
Panel
Popup Popup
TextureRect MenuButton
TextureButton Control
AudioStreamPlayer2D LineEdit
FlowContainer

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -9,8 +9,8 @@ dock_filesystem_v_split_offset=0
dock_filesystem_display_mode=0 dock_filesystem_display_mode=0
dock_filesystem_file_sort=0 dock_filesystem_file_sort=0
dock_filesystem_file_list_display_mode=1 dock_filesystem_file_list_display_mode=1
dock_filesystem_selected_paths=PackedStringArray("res://scenes/configuration.tscn") dock_filesystem_selected_paths=PackedStringArray("res://audio/wolf.mp3")
dock_filesystem_uncollapsed_paths=PackedStringArray("Favorites", "res://", "res://scripts/", "res://scenes/") dock_filesystem_uncollapsed_paths=PackedStringArray("Favorites", "res://", "res://audio/")
dock_node_current_tab=0 dock_node_current_tab=0
dock_history_include_scene=true dock_history_include_scene=true
dock_history_include_global=true dock_history_include_global=true
@ -44,7 +44,7 @@ position=Vector2i(0, 23)
[ScriptEditor] [ScriptEditor]
open_scripts=["res://scripts/configuration.gd", "res://scripts/game.gd", "res://scripts/game_data.gd", "res://scripts/screen_manager.gd"] open_scripts=["res://scripts/configuration.gd", "res://scripts/game.gd", "res://scripts/game_data.gd", "res://scripts/screen_manager.gd"]
selected_script="res://scripts/configuration.gd" selected_script="res://scripts/game.gd"
open_help=[] open_help=[]
script_split_offset=200 script_split_offset=200
list_split_offset=0 list_split_offset=0

View File

@ -1,14 +1,27 @@
ea4bc82a6ad023ab7ee23ee620429895 ea4bc82a6ad023ab7ee23ee620429895
::res://::1744847524 ::res://::1745432009
Fondo.png::CompressedTexture2D/CompressedTexture2D::2897047315587731151::1744739710::1744739716::1::::<><><>0<>0<>eacad182f531010fb24ebac1df6691a5<>res://.godot/imported/Fondo.png-90ffc355f5eaeb5a9d9680e0d0d619ff.ctex::
icon.svg::CompressedTexture2D/CompressedTexture2D::5044074093411398912::1744633584::1744633593::1::::<><><>0<>0<>f9adb246a70a7d9e0b44b9e0dce472bb<>res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex:: icon.svg::CompressedTexture2D/CompressedTexture2D::5044074093411398912::1744633584::1744633593::1::::<><><>0<>0<>f9adb246a70a7d9e0b44b9e0dce472bb<>res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex::
::res://audio/::1744635741 ::res://audio/::1745432009
asno.mp3::AudioStreamMP3::5781012165743321088::1745431872::1745432009::1::::<><><>0<>0<>04849c7d6b682c88a72746e86174f73b<>res://.godot/imported/asno.mp3-c8f31127f4b178b8b2b8415bad169e07.mp3str::
caballo.mp3::AudioStreamMP3/AudioStreamMP3::4827901584278378597::1745431804::1745431804::1::::<><><>0<>0<>6e43501dc2941926b422a069a37c5b89<>res://.godot/imported/caballo.mp3-7b2055e87f29328701251f905f0ed53e.mp3str::
cuervo.mp3::AudioStreamMP3/AudioStreamMP3::4812865155172360579::1745431882::1745431965::1::::<><><>0<>0<>18f7a5517aeb2c4811e41ee28fbdbcbb<>res://.godot/imported/cuervo.mp3-699bfa229f8863609609060333d7eb09.mp3str::
Elefant.mp3::AudioStreamMP3/AudioStreamMP3::1108392689846586874::1744635741::1744635741::1::::<><><>0<>0<>009805eb2c7d9c7cd23bd1fcf3eb7bf8<>res://.godot/imported/Elefant.mp3-e3e5c8488a65256c22d6f79b59243fe7.mp3str:: Elefant.mp3::AudioStreamMP3/AudioStreamMP3::1108392689846586874::1744635741::1744635741::1::::<><><>0<>0<>009805eb2c7d9c7cd23bd1fcf3eb7bf8<>res://.godot/imported/Elefant.mp3-e3e5c8488a65256c22d6f79b59243fe7.mp3str::
::res://scenes/::1744845819 gallo.mp3::AudioStreamMP3/AudioStreamMP3::2685061553279347517::1745431722::1745431729::1::::<><><>0<>0<>e12bc0d6db956a381fb428c74ffa81da<>res://.godot/imported/gallo.mp3-1271e286f267d5e31c477f20fe593d30.mp3str::
configuration.tscn::PackedScene::1018116344755398623::1744845798::0::1::::<><><>0<>0<><>::uid://e41ws6j00o5::::res://scripts/configuration.gd gato.mp3::AudioStreamMP3/AudioStreamMP3::5660098724051234660::1745431771::1745431930::1::::<><><>0<>0<>c8f2a66613b407ab6ee342c4cf2b03b7<>res://.godot/imported/gato.mp3-c61b66ed22aa208d5f0638a947cee007.mp3str::
game.tscn::PackedScene::6874229073676243903::1744845819::0::1::::<><><>0<>0<><>::uid://dhqnf0xm2mwwm::::res://scripts/game.gd<>uid://bhjl7furxm0dv::::res://Fondo.png gaviota.mp3::AudioStreamMP3/AudioStreamMP3::6630534147415936020::1745431879::1745431925::1::::<><><>0<>0<>1d8f8d40adc742a900f128a403114939<>res://.godot/imported/gaviota.mp3-b98dceded202a98d930f5d8b44e91302.mp3str::
::res://scripts/::1744845819 oveja.mp3::AudioStreamMP3/AudioStreamMP3::6892221899961415453::1745431841::1745431936::1::::<><><>0<>0<>6b9875df10bf634bc5185ea4479c2ce1<>res://.godot/imported/oveja.mp3-548c0afa06640f39be929ba57d20c25d.mp3str::
configuration.gd::GDScript::10065919189713686::1744845819::0::1::::<>Control<><>0<>0<><>:: perro.mp3::AudioStreamMP3/AudioStreamMP3::2363096142831056952::1745431668::1745431676::1::::<><><>0<>0<>6c8a300409787c83d6c5fda9997fc150<>res://.godot/imported/perro.mp3-70940168b9c50fc40928609c0024fb67.mp3str::
game.gd::GDScript/GDScript::7684413599682033952::1744827660::0::1::::<>Control<><>0<>0<><>:: vaca.mp3::AudioStreamMP3/AudioStreamMP3::2596745121890943594::1745431616::1745431617::1::::<><><>0<>0<>dc233f99ee2d0d4acfba4fac41e69ab3<>res://.godot/imported/vaca.mp3-6fdbb0ce8242846d3ac977450b7ac193.mp3str::
game_data.gd::GDScript/GDScript::3070763797095879381::1744824670::0::1::::<>Node<><>0<>0<><>:: wolf.mp3::AudioStreamMP3/AudioStreamMP3::4476753813126878356::1745431572::1745431573::1::::<><><>0<>0<>fe6fb338f4476d030d4e8e5517df5fa5<>res://.godot/imported/wolf.mp3-5b3e376d644832f42cc7647c484fe190.mp3str::
::res://images/::1745428753
background.png::CompressedTexture2D/CompressedTexture2D::6822232804109568982::1745428752::1745428753::1::::<><><>0<>0<>5a780c38dac7e0dc6cc39dd8f5632c97<>res://.godot/imported/background.png-23e4ff24ed3606e496e606d42ded004c.ctex::
Fondo.png::CompressedTexture2D/CompressedTexture2D::6448476263866600585::1745260713::1745260728::1::::<><><>0<>0<>a5e23edebe29509b5d3e01644f8185aa<>res://.godot/imported/Fondo.png-ba7036b5421ed7e1312c2cbc3c746cc2.ctex::
menu_logo.png::CompressedTexture2D/CompressedTexture2D::5689433748730304837::1745260946::1745260946::1::::<><><>0<>0<>aa8e65da18c85d772f423418a1d50520<>res://.godot/imported/menu_logo.png-326be22817043ae765a9aaa1fb96c9c5.ctex::
::res://scenes/::1745431061
configuration.tscn::PackedScene/PackedScene::1018116344755398623::1745431061::0::1::::<><><>0<>0<><>::uid://e41ws6j00o5::::res://scripts/configuration.gd
game.tscn::PackedScene/PackedScene::6874229073676243903::1745431061::0::1::::<><><>0<>0<><>::uid://dhqnf0xm2mwwm::::res://scripts/game.gd<>uid://c4g0gbifdm5fe::::res://images/background.png<>uid://cncae337c0ws8::::res://images/menu_logo.png
::res://scripts/::1745431061
configuration.gd::GDScript/GDScript::10065919189713686::1745414906::0::1::::<>Control<><>0<>0<><>::
game.gd::GDScript/GDScript::7684413599682033952::1745431061::0::1::::<>Control<><>0<>0<><>::
game_data.gd::GDScript/GDScript::3070763797095879381::1745431026::0::1::::<>Node<><>0<>0<><>::
screen_manager.gd::GDScript/GDScript::1421320781459715397::1744728053::0::1::::<>Node<><>0<>0<><>:: screen_manager.gd::GDScript/GDScript::1421320781459715397::1744728053::0::1::::<>Node<><>0<>0<><>::

View File

@ -1,4 +1,4 @@
res://scenes/game.tscn res://scenes/game.tscn
res://scripts/game_data.gd
res://scripts/configuration.gd
res://scenes/configuration.tscn res://scenes/configuration.tscn
res://scripts/game_data.gd
res://scripts/game.gd

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -8,7 +8,7 @@ Anim={
"grid_snap_active": false, "grid_snap_active": false,
"grid_step": Vector2(8, 8), "grid_step": Vector2(8, 8),
"grid_visibility": 1, "grid_visibility": 1,
"ofs": Vector2(-592.641, -226.488), "ofs": Vector2(-983.177, -151.558),
"primary_grid_step": Vector2i(8, 8), "primary_grid_step": Vector2i(8, 8),
"show_group_gizmos": true, "show_group_gizmos": true,
"show_guides": true, "show_guides": true,
@ -34,7 +34,7 @@ Anim={
"snap_rotation_step": 0.261799, "snap_rotation_step": 0.261799,
"snap_scale": false, "snap_scale": false,
"snap_scale_step": 0.1, "snap_scale_step": 0.1,
"zoom": 0.513158 "zoom": 0.424098
} }
3D={ 3D={
"fov": 70.01, "fov": 70.01,

View File

@ -1,5 +1,5 @@
[folding] [folding]
node_unfolds=[NodePath("TextureRect"), PackedStringArray("Layout", "Layout/Transform"), NodePath("VBoxContainer"), PackedStringArray("Layout", "Layout/Transform", "Theme", "Theme Overrides"), NodePath("VBoxContainer/NextSoundButton"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal", "Theme Overrides/font_sizes"), NodePath("VBoxContainer/HBoxContainer"), PackedStringArray("Layout", "Layout/Container Sizing"), NodePath("VBoxContainer/HBoxContainer/RepeatSoundButton"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal", "Theme Overrides/font_sizes"), NodePath("VBoxContainer/HBoxContainer/EndOfGameButton"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "Theme Overrides/font_sizes", "theme_override_styles/normal"), NodePath("WinnerSelector"), PackedStringArray("Theme Overrides", "theme_override_styles/embedded_unfocused_border", "theme_override_styles/embedded_border"), NodePath("WinnerSelector/ColorRect"), PackedStringArray("Layout"), NodePath("WinnerSelector/VBoxContainer"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/constants", "Layout/Transform"), NodePath("WinnerSelector/VBoxContainer/Label"), PackedStringArray("Layout/Container Sizing", "Theme Overrides", "Theme Overrides/colors", "Layout"), NodePath("WinnerSelector/VBoxContainer/MenuPlayers"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal", "Theme Overrides/colors"), NodePath("WinnerSelector/VBoxContainer/Button"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal"), NodePath("Bloqueador"), PackedStringArray("Layout", "Layout/Transform")] node_unfolds=[NodePath("."), PackedStringArray("Layout"), NodePath("TextureRect"), PackedStringArray("Layout", "Layout/Transform", "Layout/Container Sizing"), NodePath("CenterContainer"), PackedStringArray("Layout"), NodePath("CenterContainer/VBoxContainer"), PackedStringArray("Layout", "Layout/Transform", "Layout/Container Sizing", "Layout/Grow Direction", "Layout/Anchor Points", "Layout/Anchor Offsets"), NodePath("CenterContainer/VBoxContainer/NextSoundButton"), PackedStringArray("Layout", "Theme Overrides/font_sizes", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal", "Layout/Container Sizing", "theme_override_styles/pressed", "Focus"), NodePath("CenterContainer/VBoxContainer/HBoxContainer"), PackedStringArray("Layout", "Layout/Container Sizing"), NodePath("CenterContainer/VBoxContainer/HBoxContainer/RepeatSoundButton"), PackedStringArray("Layout", "Layout/Container Sizing", "theme_override_styles/normal", "Theme Overrides/font_sizes", "Focus"), NodePath("CenterContainer/VBoxContainer/HBoxContainer/EndOfGameButton"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "Theme Overrides/font_sizes", "theme_override_styles/normal", "Focus"), NodePath("WinnerSelector"), PackedStringArray("Theme Overrides", "theme_override_styles/embedded_unfocused_border", "theme_override_styles/embedded_border"), NodePath("WinnerSelector/ColorRect"), PackedStringArray("Layout"), NodePath("WinnerSelector/VBoxContainer"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/constants", "Layout/Transform"), NodePath("WinnerSelector/VBoxContainer/Label"), PackedStringArray("Layout/Container Sizing", "Theme Overrides", "Theme Overrides/colors", "Layout"), NodePath("WinnerSelector/VBoxContainer/MenuPlayers"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal", "Theme Overrides/colors"), NodePath("WinnerSelector/VBoxContainer/Button"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal"), NodePath("Bloqueador"), PackedStringArray("Layout", "Layout/Transform"), NodePath("ExitButtonWindow/ColorRect"), PackedStringArray("Layout", "Layout/Container Sizing"), NodePath("ExitButtonWindow/VBoxContainer"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/constants"), NodePath("ExitButtonWindow/VBoxContainer/Label"), PackedStringArray("Theme Overrides", "Theme Overrides/colors", "Theme Overrides/font_sizes"), NodePath("ExitButtonWindow/VBoxContainer/HBoxContainer/ConfirmExitButton"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal"), NodePath("ExitButtonWindow/VBoxContainer/HBoxContainer/CancelExitButton"), PackedStringArray("Layout", "Layout/Container Sizing", "Theme Overrides", "Theme Overrides/styles", "theme_override_styles/normal")]
resource_unfolds=["res://scenes/game.tscn::StyleBoxFlat_yqjtg", PackedStringArray("Corner Radius"), "res://scenes/game.tscn::StyleBoxFlat_lnu2h", PackedStringArray("Corner Radius"), "res://scenes/game.tscn::StyleBoxFlat_lbhrr", PackedStringArray("Corner Radius"), "res://scenes/game.tscn::StyleBoxFlat_iywne", PackedStringArray(), "res://scenes/game.tscn::StyleBoxFlat_p57ef", PackedStringArray()] resource_unfolds=["res://scenes/game.tscn::StyleBoxFlat_0tnpc", PackedStringArray("Border", "Corner Radius"), "res://scenes/game.tscn::StyleBoxFlat_yqjtg", PackedStringArray("Corner Radius", "Border", "Border Width"), "res://scenes/game.tscn::StyleBoxFlat_lnu2h", PackedStringArray("Corner Radius", "Border", "Border Width"), "res://scenes/game.tscn::StyleBoxFlat_lbhrr", PackedStringArray("Corner Radius", "Border", "Border Width"), "res://scenes/game.tscn::StyleBoxFlat_iywne", PackedStringArray(), "res://scenes/game.tscn::StyleBoxFlat_p57ef", PackedStringArray(), "res://scenes/game.tscn::StyleBoxFlat_u5sy4", PackedStringArray(), "res://scenes/game.tscn::StyleBoxFlat_gee14", PackedStringArray()]
nodes_folded=[NodePath("VBoxContainer"), NodePath("WinnerSelector"), NodePath("WinnerSelector/VBoxContainer")] nodes_folded=[NodePath("WinnerSelector"), NodePath("WinnerSelector/VBoxContainer"), NodePath("ExitButtonWindow"), NodePath("ExitButtonWindow/VBoxContainer"), NodePath("ExitButtonWindow/VBoxContainer/HBoxContainer")]

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -20,7 +20,7 @@ scenes=["res://scenes/configuration.tscn", "res://scenes/game.tscn", "res://game
[color_picker] [color_picker]
picker_shape=3 picker_shape=3
recent_presets=PackedColorArray(0.811765, 0, 0, 1, 0.545498, 3.1285e-07, 0.261076, 1, 1, 1, 1, 1, 0.8, 0.8, 0.8, 1, 0.588235, 0.654902, 0.686275, 1, 0.196078, 0.309804, 0.368627, 0.956863, 0.196078, 0.309804, 0.368627, 1, 0.196078, 0.309804, 0.368627, 0.784314, 0.588235, 0.654902, 0.686275, 1) recent_presets=PackedColorArray(0.588235, 0.654902, 0.686275, 1, 0.588235, 0.654902, 0.686275, 1, 0.8, 0.8, 0.8, 1, 0.196078, 0.309804, 0.368627, 1, 0.0156863, 0.8, 0.8, 1, 0.0156863, 0.247059, 0.8, 1, 0.92549, 0.376471, 0.615686, 1, 0.92549, 0.376471, 0.615686, 0.788235, 0, 0, 0, 1)
[quick_open_dialog] [quick_open_dialog]

View File

@ -3,16 +3,12 @@
state={ state={
"bookmarks": PackedInt32Array(), "bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(), "breakpoints": PackedInt32Array(),
"column": 27, "column": 0,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 0, "h_scroll_position": 0,
"row": 54, "row": 11,
"scroll_position": 12.0, "scroll_position": 0.0,
"selection": true, "selection": false,
"selection_from_column": 20,
"selection_from_line": 54,
"selection_to_column": 27,
"selection_to_line": 54,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }
@ -21,11 +17,11 @@ state={
state={ state={
"bookmarks": PackedInt32Array(), "bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(), "breakpoints": PackedInt32Array(),
"column": 40, "column": 35,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 0, "h_scroll_position": 0,
"row": 89, "row": 98,
"scroll_position": 69.0, "scroll_position": 0.0,
"selection": false, "selection": false,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }
@ -52,8 +48,8 @@ state={
"column": 25, "column": 25,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 0, "h_scroll_position": 0,
"row": 22, "row": 65,
"scroll_position": 18.0, "scroll_position": 49.0,
"selection": false, "selection": false,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

Some files were not shown because too many files have changed in this diff Show More