diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 8ef054b..96bd4d5 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; +import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import { Helmet } from 'react-helmet'; import './App.css'; import Header from './components/header'; @@ -10,6 +10,7 @@ import JoinGame from './pages/joinGame'; import StartGame from './pages/startGame'; import Profile from './pages/profile'; import Games from './pages/games.jsx'; +import CreateCharacter from './pages/createCharacter.jsx'; import { UserProvider } from './context/UserContext.jsx'; function App() { @@ -23,13 +24,13 @@ function App() { return ( - +
- + P&P-Master - {popupMessage &&
{popupMessage}
} + {popupMessage &&
{popupMessage}
}
@@ -64,6 +65,10 @@ function App() { path='/games/:gameId' element={} /> + } + />
diff --git a/frontend/src/pages/createCharacter.jsx b/frontend/src/pages/createCharacter.jsx new file mode 100644 index 0000000..d9c1379 --- /dev/null +++ b/frontend/src/pages/createCharacter.jsx @@ -0,0 +1,419 @@ +import React, { useState, useContext } from 'react'; +import { useNavigate, useLocation } from 'react-router-dom'; +import { UserContext } from '../context/UserContext'; +import axios from 'axios'; +import { + Box, + TextField, + Button, + Typography, + Select, + MenuItem, + FormControl, + InputLabel, + Grid2 +} from '@mui/material'; + +const CreateCharacter = () => { + const navigate = useNavigate(); + const location = useLocation(); + const { userId } = useContext(UserContext); + const gameId = new URLSearchParams(location.search).get('gameId'); + + const [formData, setFormData] = useState({ + charName: '', + race: '', + sex: '', + age: '', + job: '', + description: '', + maxHealth: 100, + maxMana: 100, + strength: 10, + dexterity: 10, + agility: 10, + endurance: 10 + }); + + const [selectedImage, setSelectedImage] = useState(null); + const [imagePreview, setImagePreview] = useState(null); + + const handleChange = (e) => { + setFormData({ + ...formData, + [e.target.name]: e.target.value + }); + }; + + const handleImageChange = (e) => { + const file = e.target.files[0]; + if (file) { + setSelectedImage(file); + setImagePreview(URL.createObjectURL(file)); + } + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + const formDataToSend = new FormData(); + + // Append all form data + Object.keys(formData).forEach(key => { + formDataToSend.append(key, formData[key]); + }); + + // Append image if exists + if (selectedImage) { + formDataToSend.append('image', selectedImage); + } + + try { + await axios.post('http://localhost:5000/games/character/create', + formDataToSend, + { + headers: { + 'Content-Type': 'multipart/form-data' + } + } + ); + navigate(`/games/${gameId}`); + } catch (error) { + console.error('Error creating character:', error); + } + }; + + return ( + + + Create New Character + + +
+ + {/* Basic Info */} + + + + + {/* Image Upload */} + + + + {imagePreview && ( + + Preview + + )} + + + {/* Character Details */} + + + + Race + + + + + + + Sex + + + + + + + + + + + + + {/* Stats */} + + + + + + + + + + + + + + + + + + + + + + + + + {/* Description */} + + + + + + + +
+
+ ); +}; + +export default CreateCharacter; \ No newline at end of file diff --git a/frontend/src/pages/games.jsx b/frontend/src/pages/games.jsx index 6868b88..d1c8ef8 100644 --- a/frontend/src/pages/games.jsx +++ b/frontend/src/pages/games.jsx @@ -100,7 +100,7 @@ const GamesPage = () => { } }} component={Link} - to="/create-character" + to={`/create-character?gameId=${gameId}`} > Create New Character