diff --git a/backend/database.db b/backend/database.db index 8461bbf..d0962dd 100644 Binary files a/backend/database.db and b/backend/database.db differ diff --git a/backend/server.js b/backend/server.js index 0b9565d..3ee6d7b 100644 --- a/backend/server.js +++ b/backend/server.js @@ -192,7 +192,44 @@ app.get('/games/:gameId/items', (req, res) => { }); }) + // Player Part + +// Create Player Character +app.post('/games/character/create', upload.single('image'), (req, res) => { + const { + charName, race, sex, age, job, description, + maxHealth, maxMana, strength, dexterity, agility, endurance, + gameId, playerId + } = req.body; + + const imageBuffer = req.file ? req.file.buffer : null; + + const stmt = db.prepare(` + INSERT INTO PlayerCharacter ( + GameID, PlayerID, CharName, Race, Sex, Age, Job, + description, maxHealth, currentHealth, maxMana, currentMana, + Strength, Dexterity, Agility, Endurance, Level, Gold, Img + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0, ?) + `); + + stmt.run([ + gameId, playerId, charName, race, sex, age, job, + description, maxHealth, maxHealth, maxMana, maxMana, + strength, dexterity, agility, endurance, imageBuffer + ], function(err) { + if (err) { + console.error('Database error:', err); + return res.status(500).json({ error: 'Internal server error' }); + } + res.status(201).json({ + message: 'Character created successfully!', + characterId: this.lastID + }); + }); + stmt.finalize(); +}); + // Fetch all Player Characters of Player app.get('/games/:userId/characters', (req, res) => { const userId = req.params.userId; diff --git a/frontend/src/assets/catiana.png b/frontend/src/assets/catiana.png new file mode 100644 index 0000000..2c359ff Binary files /dev/null and b/frontend/src/assets/catiana.png differ diff --git a/frontend/src/pages/createCharacter.jsx b/frontend/src/pages/createCharacter.jsx index d9c1379..f8e1e47 100644 --- a/frontend/src/pages/createCharacter.jsx +++ b/frontend/src/pages/createCharacter.jsx @@ -2,17 +2,19 @@ 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'; +import { Box, TextField, Button, Typography, Select, MenuItem, FormControl, InputLabel, Grid2, Card, CardContent, CardMedia, Menu } from '@mui/material'; + +// Import the same icons as in games.jsx +import PaidIcon from '@mui/icons-material/Paid'; +import CalendarTodayIcon from '@mui/icons-material/CalendarToday'; +import PetsIcon from '@mui/icons-material/Pets'; +import WcIcon from '@mui/icons-material/Wc'; +import WorkIcon from '@mui/icons-material/Work'; +import HeartIcon from '@mui/icons-material/Favorite'; +import WaterDropIcon from '@mui/icons-material/WaterDrop'; +import KeyboardDoubleArrowUpIcon from '@mui/icons-material/KeyboardDoubleArrowUp'; + +import defaultCharacterImage from '../assets/default-character.png'; const CreateCharacter = () => { const navigate = useNavigate(); @@ -57,363 +59,365 @@ const CreateCharacter = () => { e.preventDefault(); const formDataToSend = new FormData(); - // Append all form data + // Add all form data Object.keys(formData).forEach(key => { - formDataToSend.append(key, formData[key]); + formDataToSend.append(key, formData[key]); }); - // Append image if exists + // Add image if selected if (selectedImage) { - formDataToSend.append('image', selectedImage); + formDataToSend.append('image', selectedImage); } + // Add gameId and playerId + formDataToSend.append('gameId', gameId); + formDataToSend.append('playerId', userId); + try { - await axios.post('http://localhost:5000/games/character/create', - formDataToSend, - { - headers: { - 'Content-Type': 'multipart/form-data' - } + const response = await axios.post( + 'http://localhost:5000/games/character/create', + formDataToSend, + { + headers: { + 'Content-Type': 'multipart/form-data' + } + } + ); + + if (response.status === 201) { + // Redirect to the game page after successful character creation + navigate(`/games/${gameId}`); } - ); - navigate(`/games/${gameId}`); } catch (error) { - console.error('Error creating character:', error); + console.error('Error creating character:', error); + // You might want to show an error message to the user here } +}; + + const inputStyles = { + '& .MuiOutlinedInput-root': { + '& fieldset': { borderColor: '#444' }, + '&:hover fieldset': { borderColor: '#764ACB' }, + '&.Mui-focused fieldset': { borderColor: '#764ACB' }, + }, + '& .MuiInputLabel-root': { color: '#fff' }, + '& .MuiInputBase-input': { color: '#fff' } }; return ( - - - Create New Character - - +
- - {/* Basic Info */} - - - + + {/* Character Image and Details */} + + + + {imagePreview ? ( + + + + + ) : ( + + + + + )} + + - {/* Image Upload */} - - - - {imagePreview && ( - - Preview - - )} - + + + + + + + + + + Sex + + + + + + + + + + + - {/* Character Details */} - - - - Race - - - - - - - Sex - - - - - - - - - - - - - {/* Stats */} - - - - - - - - - - - - - - - - - - - - - - - + sx={{ + '& .MuiOutlinedInput-root': { + '& fieldset': { borderColor: '#444' }, + '&:hover fieldset': { borderColor: '#764ACB' }, + }, + '& .MuiInputBase-input': { color: '#fff' } + }} + /> + + {/* Description */} - - - - - + + Description + + + + - - -
+ {/* Stats Grid */} + + Character Stats + + + + + + + + + + + + + + + + + + + + {/* Submit Button */} + + + + +
); }; -export default CreateCharacter; \ No newline at end of file +export default CreateCharacter; diff --git a/test/catiana.png b/test/catiana.png new file mode 100644 index 0000000..2c359ff Binary files /dev/null and b/test/catiana.png differ diff --git a/test/test.js b/test/test.js index 70411df..83a2fb2 100644 --- a/test/test.js +++ b/test/test.js @@ -27,8 +27,8 @@ async function uploadImage(imagePath, gameId, userId) { // Example usage: // Replace these values with your actual gameId and userId -const gameId = 'eb82723d'; +const gameId = 'd7997cfd'; const userId = '1'; -const imagePath = './female-char.png'; +const imagePath = './catiana.png'; uploadImage(imagePath, gameId, userId); \ No newline at end of file