// Exemplo de componente de registro de execução de treino em React
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const TrainingExecution = ({ trainingId }) => {
const [training, setTraining] = useState(null);
const [execution, setExecution] = useState({
startTime: new Date().toISOString(),
endTime: null,
notes: '',
completed: false,
exerciseExecutions: []
});
const [loading, setLoading] = useState(true);
const [submitting, setSubmitting] = useState(false);
const [error, setError] = useState(null);
const [success, setSuccess] = useState(false);
useEffect(() => {
// Carregar detalhes do treino
const fetchTraining = async () => {
try {
setLoading(true);
const response = await axios.get(`/trainings/${trainingId}`);
setTraining(response.data);
// Inicializar execuções de exercícios
const initialExerciseExecutions = response.data.exercises.map(exercise => ({
exerciseId: exercise.exerciseId,
exerciseName: exercise.exerciseName,
sets: Array(exercise.sets).fill().map(() => ({
repetitions: 0,
weight: 0,
completed: false
}))
}));
setExecution(prev => ({
...prev,
exerciseExecutions: initialExerciseExecutions
}));
setLoading(false);
} catch (err) {
setError(err.response?.data?.message || 'Erro ao carregar treino');
setLoading(false);
}
};
fetchTraining();
}, [trainingId]);
const handleSetChange = (exerciseIndex, setIndex, field, value) => {
const newExerciseExecutions = [...execution.exerciseExecutions];
newExerciseExecutions[exerciseIndex].sets[setIndex] = {
...newExerciseExecutions[exerciseIndex].sets[setIndex],
[field]: field === 'completed' ? value : Number(value)
};
setExecution(prev => ({
...prev,
exerciseExecutions: newExerciseExecutions
}));
};
const handleNotesChange = (e) => {
setExecution(prev => ({
...prev,
notes: e.target.value
}));
};
const handleSubmit = async () => {
// Validação básica
if (execution.exerciseExecutions.some(ex => ex.sets.every(set => !set.completed))) {
setError('Complete pelo menos uma série de cada exercício');
return;
}
setSubmitting(true);
setError(null);
setSuccess(false);
// Definir horário de término
const endTime = new Date().toISOString();
try {
const response = await axios.post(`/trainings/${trainingId}/execution`, {
...execution,
endTime,
completed: true
});
setSubmitting(false);
setSuccess(true);
} catch (err) {
setSubmitting(false);
setError(err.response?.data?.message || 'Erro ao registrar execução');
}
};
if (loading) return <div>Carregando...</div>;
if (error && !training) return <div>Erro: {error}</div>;
if (!training) return <div>Treino não encontrado</div>;
return (
<div className="training-execution">
<h2>Executar Treino: {training.name}</h2>
<p className="description">{training.description}</p>
{error && <div className="error-message">{error}</div>}
{success && <div className="success-message">Treino registrado com sucesso!</div>}
<div className="exercises">
{execution.exerciseExecutions.map((exerciseExecution, exerciseIndex) => (
<div key={exerciseExecution.exerciseId} className="exercise-execution">
<h3>{exerciseExecution.exerciseName}</h3>
<div className="sets-container">
<div className="sets-header">
<span>Série</span>
<span>Repetições</span>
<span>Carga (kg)</span>
<span>Concluída</span>
</div>
{exerciseExecution.sets.map((set, setIndex) => (
<div key={setIndex} className="set-row">
<span>{setIndex + 1}</span>
<input
type="number"
min="0"
value={set.repetitions}
onChange={(e) => handleSetChange(exerciseIndex, setIndex, 'repetitions', e.target.value)}
/>
<input
type="number"
min="0"
step="0.5"
value={set.weight}
onChange={(e) => handleSetChange(exerciseIndex, setIndex, 'weight', e.target.value)}
/>
<input
type="checkbox"
checked={set.completed}
onChange={(e) => handleSetChange(exerciseIndex, setIndex, 'completed', e.target.checked)}
/>
</div>
))}
</div>
</div>
))}
</div>
<div className="form-group">
<label>Observações</label>
<textarea
value={execution.notes}
onChange={handleNotesChange}
placeholder="Opcional: Adicione observações sobre o treino"
/>
</div>
<button
type="button"
onClick={handleSubmit}
disabled={submitting}
>
{submitting ? 'Registrando...' : 'Concluir Treino'}
</button>
</div>
);
};
export default TrainingExecution;