// Exemplo de componente de criação de exercício em React
import React, { useState } from 'react';
import axios from 'axios';
const ExerciseForm = () => {
const [exercise, setExercise] = useState({
name: '',
description: '',
category: '',
isPublic: false,
difficulty: '',
equipment: '',
videoUrl: '',
instructions: [''],
muscleGroups: []
});
const [file, setFile] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [success, setSuccess] = useState(false);
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
setExercise(prev => ({
...prev,
[name]: type === 'checkbox' ? checked : value
}));
};
const handleInstructionChange = (index, value) => {
const newInstructions = [...exercise.instructions];
newInstructions[index] = value;
setExercise(prev => ({
...prev,
instructions: newInstructions
}));
};
const addInstruction = () => {
setExercise(prev => ({
...prev,
instructions: [...prev.instructions, '']
}));
};
const removeInstruction = (index) => {
const newInstructions = [...exercise.instructions];
newInstructions.splice(index, 1);
setExercise(prev => ({
...prev,
instructions: newInstructions
}));
};
const handleMuscleGroupChange = (e) => {
const { value, checked } = e.target;
setExercise(prev => ({
...prev,
muscleGroups: checked
? [...prev.muscleGroups, value]
: prev.muscleGroups.filter(group => group !== value)
}));
};
const handleFileChange = (e) => {
const selectedFile = e.target.files[0];
// Validação básica do arquivo
if (selectedFile) {
if (!['image/jpeg', 'image/png', 'image/gif'].includes(selectedFile.type)) {
setError('Formato de arquivo inválido. Use JPG, PNG ou GIF.');
return;
}
if (selectedFile.size > 5 * 1024 * 1024) {
setError('Arquivo muito grande. Tamanho máximo: 5MB.');
return;
}
setFile(selectedFile);
setError(null);
}
};
const handleSubmit = async (e) => {
e.preventDefault();
// Validação básica
if (!exercise.name || !exercise.description || !exercise.category) {
setError('Preencha todos os campos obrigatórios.');
return;
}
setLoading(true);
setError(null);
setSuccess(false);
const formData = new FormData();
// Remover instruções vazias
const cleanedExercise = {
...exercise,
instructions: exercise.instructions.filter(instruction => instruction.trim() !== '')
};
formData.append('exercise', JSON.stringify(cleanedExercise));
if (file) {
formData.append('file', file);
}
try {
const response = await axios.post('/exercises', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
setLoading(false);
setSuccess(true);
// Resetar formulário
setExercise({
name: '',
description: '',
category: '',
isPublic: false,
difficulty: '',
equipment: '',
videoUrl: '',
instructions: [''],
muscleGroups: []
});
setFile(null);
} catch (err) {
setLoading(false);
setError(err.response?.data?.message || 'Erro ao criar exercício');
}
};
return (
<div className="exercise-form">
<h2>Criar Novo Exercício</h2>
{error && <div className="error-message">{error}</div>}
{success && <div className="success-message">Exercício criado com sucesso!</div>}
<form onSubmit={handleSubmit}>
<div className="form-group">
<label>Nome *</label>
<input
type="text"
name="name"
value={exercise.name}
onChange={handleChange}
required
/>
</div>
<div className="form-group">
<label>Descrição *</label>
<textarea
name="description"
value={exercise.description}
onChange={handleChange}
required
/>
</div>
<div className="form-group">
<label>Categoria *</label>
<select
name="category"
value={exercise.category}
onChange={handleChange}
required
>
<option value="">Selecione uma categoria</option>
<option value="PEITO">Peito</option>
<option value="COSTAS">Costas</option>
<option value="OMBRO">Ombro</option>
<option value="BICEPS">Bíceps</option>
<option value="TRICEPS">Tríceps</option>
<option value="PERNAS">Pernas</option>
<option value="ABDOMEN">Abdômen</option>
<option value="GLUTEOS">Glúteos</option>
<option value="CARDIO">Cardio</option>
<option value="OUTRO">Outro</option>
</select>
</div>
<div className="form-group">
<label>Dificuldade</label>
<select
name="difficulty"
value={exercise.difficulty}
onChange={handleChange}
>
<option value="">Selecione a dificuldade</option>
<option value="INICIANTE">Iniciante</option>
<option value="INTERMEDIARIO">Intermediário</option>
<option value="AVANCADO">Avançado</option>
</select>
</div>
<div className="form-group">
<label>Equipamento</label>
<select
name="equipment"
value={exercise.equipment}
onChange={handleChange}
>
<option value="">Selecione o equipamento</option>
<option value="BARRA">Barra</option>
<option value="HALTERES">Halteres</option>
<option value="MAQUINA">Máquina</option>
<option value="CABO">Cabo</option>
<option value="PESO_CORPORAL">Peso Corporal</option>
<option value="OUTRO">Outro</option>
</select>
</div>
<div className="form-group">
<label>URL do Vídeo</label>
<input
type="url"
name="videoUrl"
value={exercise.videoUrl}
onChange={handleChange}
placeholder="https://www.youtube.com/watch?v=exemplo"
/>
</div>
<div className="form-group">
<label>Imagem Demonstrativa</label>
<input
type="file"
accept="image/jpeg,image/png,image/gif"
onChange={handleFileChange}
/>
<small>Formatos aceitos: JPG, PNG, GIF. Tamanho máximo: 5MB.</small>
</div>
<div className="form-group">
<label>Instruções</label>
{exercise.instructions.map((instruction, index) => (
<div key={index} className="instruction-row">
<input
type="text"
value={instruction}
onChange={(e) => handleInstructionChange(index, e.target.value)}
placeholder={`Passo ${index + 1}`}
/>
<button
type="button"
onClick={() => removeInstruction(index)}
disabled={exercise.instructions.length === 1}
>
Remover
</button>
</div>
))}
<button type="button" onClick={addInstruction}>
Adicionar Instrução
</button>
</div>
<div className="form-group">
<label>Grupos Musculares Secundários</label>
<div className="checkbox-group">
{["PEITO", "COSTAS", "OMBRO", "BICEPS", "TRICEPS", "PERNAS", "ABDOMEN", "GLUTEOS"].map(group => (
<label key={group} className="checkbox-label">
<input
type="checkbox"
value={group}
checked={exercise.muscleGroups.includes(group)}
onChange={handleMuscleGroupChange}
/>
{group.charAt(0) + group.slice(1).toLowerCase()}
</label>
))}
</div>
</div>
<div className="form-group">
<label className="checkbox-label">
<input
type="checkbox"
name="isPublic"
checked={exercise.isPublic}
onChange={handleChange}
/>
Tornar exercício público
</label>
<small>Exercícios públicos podem ser vistos e utilizados por outros usuários.</small>
</div>
<button type="submit" disabled={loading}>
{loading ? 'Criando...' : 'Criar Exercício'}
</button>
</form>
</div>
);
};
export default ExerciseForm;