From cd892a10dcc741035acb28032da871fe6386733b Mon Sep 17 00:00:00 2001 From: singharaj usai Date: Fri, 18 Oct 2024 03:05:43 -0400 Subject: [PATCH] display games and shirts in my/create fixed --- .env.example | 24 +++++- .gitignore | 2 +- client/html/pages/my/create/create.html | 1 + client/js/components/user-games.js | 98 +++++++++++-------------- client/js/places.js | 10 ++- client/js/shirts.js | 75 +++++++++++-------- client/js/user-profile.js | 2 +- server/functions/api/routes/avatar.js | 1 + server/functions/api/routes/games.js | 92 +++++++++++++---------- server/functions/api/routes/shirt.js | 39 +++++----- 10 files changed, 192 insertions(+), 152 deletions(-) diff --git a/.env.example b/.env.example index fbd38d6..0e1f4a5 100644 --- a/.env.example +++ b/.env.example @@ -1,15 +1,33 @@ MONGODB_URI=mongodb+srv://usais:fast12@cluster0.isaat.mongodb.net/ JWT_SECRET=your_very_long_and_secure_random_string_here -MAINTENANCE_MODE=false +MAINTENANCE_MODE=true + +MAINTENANCE_SECRET_KEY=mrbobbillyssecretkey +ENCRYPTION_KEY=BTFXRj0jrxSbaTKOj+aUVw3wPBIFKCx2/qveUxaIErJuVNDEXz9wvXmPuYAInkUS + +UPLOAD_ACCESS_KEY=518484 MAILCHIMP_API_KEY=8bdf84c00e127f26802a94474aa96bdf-us17 MAILCHIMP_SERVER_PREFIX=https://us17.admin.mailchimp.com/ MAILCHIMP_LIST_ID=bee92a5a1e -EMAIL_USERNAME=support@valk.fun -EMAIL_FROM_NAME=Valkyrie Support +EMAIL_USERNAME=support@alphablox.net +EMAIL_FROM_NAME=Alphablox Support GOOGLE_CLIENT_ID=914198737416-ib8t5ejpv3kidadqlmi0q3dap9g10eih.apps.googleusercontent.com GOOGLE_CLIENT_SECRET=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 GOOGLE_REFRESH_TOKEN=1//04SMY1UGhY3HMCgYIARAAGAQSNwF-L9IrAavadS_tNXtDaHhBQhTcOuD0fo38j-jJ4AzWx7MsoOdc9fXoApn5VTeTc559W0PN7Zw GOOGLE_REDIRECT_URI=https://developers.google.com/oauthplayground + +AWS_ACCESS_KEY_ID=AKIAQ4J5YFDU7HIC2XMC +AWS_SECRET_ACCESS_KEY=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 +AWS_REGION=us-east-2 +AWS_S3_BUCKET_NAME=c2.rblx18.com + +BASE_URL=www.valk.fun + +EMAIL_USER=djjd22938@gmail.com +EMAIL_PASS=iazx mivw xuhi ixcq + + +CLOUDFLARE_SECRET_KEY=0x4AAAAAAAw6-naWF42EyvhyITGX4NRuBqc diff --git a/.gitignore b/.gitignore index 662adca..99a032c 100644 --- a/.gitignore +++ b/.gitignore @@ -82,7 +82,7 @@ web_modules/ # parcel-bundler cache (https://parceljs.org/) .cache .parcel-cache - +.cursorrules # Next.js build output .next out diff --git a/client/html/pages/my/create/create.html b/client/html/pages/my/create/create.html index 72f45ff..14cafa6 100644 --- a/client/html/pages/my/create/create.html +++ b/client/html/pages/my/create/create.html @@ -58,6 +58,7 @@
+
diff --git a/client/js/components/user-games.js b/client/js/components/user-games.js index a9d09ce..31b3391 100644 --- a/client/js/components/user-games.js +++ b/client/js/components/user-games.js @@ -22,13 +22,13 @@ function displayPlacesPanel(user) { `; $('#user-places-panel').html(placesHtml); - fetchUserPlaces(user.username); + fetchUserPlaces(user.userId); } -function fetchUserPlaces(username) { +function fetchUserPlaces(userId) { const token = localStorage.getItem('token'); $.ajax({ - url: `/api/games/user/${username}`, + url: `/api/games/user/${userId}`, method: 'GET', headers: { Authorization: `Bearer ${token}`, @@ -64,66 +64,50 @@ function displayPlaces(places, category) { places.forEach((place, index) => { const placeHtml = ` -
- -
-
-
-
- - ${escapeHtml(
-      place.title
-    )} - - Play -
-
-

Genre: ${escapeHtml( - place.genre || 'Not specified' - )}

-

Max Players: ${ - place.maxPlayers || 'Not specified' - }

-

- Year: - ${ - place.year - ? `${place.year}` - : 'No Year' - } -

-

Last Updated: ${new Date( - place.updatedAt - ).toLocaleDateString()}

-
+
+ +
+
+
+
+ + ${escapeHtml(place.title)} + + Play +
+
+

Genre: ${escapeHtml(place.genre || 'Not specified')}

+

Max Players: ${place.maxPlayers || 'Not specified'}

+

+ Year: + ${place.year + ? `${place.year}` + : 'No Year' + } +

+

Last Updated: ${new Date(place.updatedAt).toLocaleDateString()}

-
-
-
-

${escapeHtml(place.description)}

-
+
+
+
+
+

${escapeHtml(place.description)}

- `; +
+ `; placesContainer.append(placeHtml); }); } diff --git a/client/js/places.js b/client/js/places.js index b08dac6..835dd27 100644 --- a/client/js/places.js +++ b/client/js/places.js @@ -30,8 +30,10 @@ $(document).ready(function () { function fetchUserGames() { const token = localStorage.getItem('token'); + const userId = localStorage.getItem('userId'); + $.ajax({ - url: '/api/games/user', + url: `/api/games/user/${userId}`, method: 'GET', headers: { Authorization: `Bearer ${token}`, @@ -239,7 +241,11 @@ $(document).ready(function () { }, success: function (response) { $('#editGameModal').modal('hide'); - fetchUserGames(); // Refresh the games list + showSuccess('Game updated successfully'); + setTimeout(() => { + fetchUserGames(); // Refresh the games list + }, 1000); + }, error: function (xhr, status, error) { let errorMessage = 'Error updating game: '; diff --git a/client/js/shirts.js b/client/js/shirts.js index 1bb21ff..502d972 100644 --- a/client/js/shirts.js +++ b/client/js/shirts.js @@ -12,11 +12,17 @@ function loadShirts() { headers: { Authorization: `Bearer ${token}`, }, - success: function (shirts) { - displayShirts(shirts); + success: function (response) { + if (response.shirts && Array.isArray(response.shirts)) { + displayShirts(response.shirts); + } else { + console.error('Invalid response format:', response); + showError('Error: Invalid response format from the server.'); + } }, error: function (xhr, status, error) { console.error('Error fetching shirts:', error); + showError('Error fetching shirts. Please try again later.'); }, }); } @@ -31,43 +37,48 @@ function displayShirts(shirts) { } const table = $(` - - - - - - - - - - - - - -
ThumbnailTitleDescriptionAsset IDPriceActions
- `); + + + + + + + + + + + + + +
ThumbnailTitleDescriptionAsset IDPriceActions
+ `); const tableBody = table.find('tbody'); shirts.forEach((shirt) => { const row = $(` - - ${shirt.Name} - ${shirt.Name} - ${shirt.Description.substring(0, 50)}${shirt.Description.length > 50 ? '...' : ''} - ${shirt.assetId} - ${shirt.Price} - - - - - `); + + ${shirt.Name} + ${shirt.Name} + ${shirt.Description.substring(0, 50)}${shirt.Description.length > 50 ? '...' : ''} + ${shirt.assetId} + ${shirt.Price} + + + + + `); tableBody.append(row); }); shirtsContainer.append(table); } +function showError(message) { + const errorContainer = $('#error-container'); + errorContainer.html(`
${message}
`); +} + function setupShirtToggler() { $('#list-tab a').on('click', function (e) { e.preventDefault(); @@ -122,7 +133,7 @@ function saveShirtChanges() { const shirtData = { title: title, description: description, - price: price, + price: parseInt(price, 10) }; $.ajax({ @@ -139,8 +150,12 @@ function saveShirtChanges() { }, error: function (xhr, status, error) { console.error('Error updating shirt:', error); + let errorMessage = 'Error updating shirt'; + if (xhr.responseJSON && xhr.responseJSON.error) { + errorMessage += ': ' + xhr.responseJSON.error; + } $('#shirt-error-message') - .text('Error updating shirt: ' + xhr.responseJSON.error) + .text(errorMessage) .removeClass('hidden'); }, }); diff --git a/client/js/user-profile.js b/client/js/user-profile.js index 1615f5b..d1f1557 100644 --- a/client/js/user-profile.js +++ b/client/js/user-profile.js @@ -589,7 +589,7 @@ $(document).ready(function () { const shirtHtml = generateItemHtml( shirt.Name, shirt.ThumbnailLocation, - shirt.creator.username, + shirt.creator ? shirt.creator.username : 'Unknown', shirt.Price ); shirtsContainer.append(shirtHtml); diff --git a/server/functions/api/routes/avatar.js b/server/functions/api/routes/avatar.js index 4995f11..f92f409 100644 --- a/server/functions/api/routes/avatar.js +++ b/server/functions/api/routes/avatar.js @@ -2,6 +2,7 @@ const express = require('express'); const router = express.Router(); const authenticateToken = require('../middleware/authenticateToken'); const User = require('../models/User'); +const mongoose = require('mongoose'); // Get current avatar router.get('/', authenticateToken, async (req, res) => { diff --git a/server/functions/api/routes/games.js b/server/functions/api/routes/games.js index e2a6c1a..e354b87 100644 --- a/server/functions/api/routes/games.js +++ b/server/functions/api/routes/games.js @@ -67,6 +67,49 @@ async function getNextAssetId() { return counter.seq; } + + +router.get('/user/:userId', authenticateToken, async (req, res) => { + try { + const userId = req.params.userId; + const user = await User.findOne({ userId: userId }); + + if (!user) { + return res.status(404).json({ error: 'User not found' }); + } + + const games = await Game.find({ creator: user._id }).sort({ + createdAt: -1, + }).populate('creator', 'username userId'); + + res.json(games); + } catch (error) { + console.error('Error fetching user games:', error); + res.status(500).json({ error: 'Internal server error', details: error.message }); + } +}); + +router.get('/:id', authenticateToken, async (req, res) => { + try { + const id = req.params.id; + const game = await Game.findOne({ _id: id, AssetType: 'Place' }).populate( + 'creator', + 'username userId' + ); + if (!game) { + return res.status(404).json({ error: 'Game not found' }); + } + res.json(game); + } catch (error) { + console.error('Error fetching game:', error); + res + .status(500) + .json({ error: 'Error fetching game', details: error.message }); + } +}); + + + router.post( '/upload', authenticateToken, @@ -218,17 +261,19 @@ router.get('/user', authenticateToken, async (req, res) => { }); // New route to update a game -router.put( - '/:id', - authenticateToken, - upload.single('thumbnail'), - async (req, res) => { +router.put('/:id', authenticateToken, upload.single('thumbnail'), async (req, res) => { try { const { id } = req.params; const { title, description, genre, maxPlayers, year } = req.body; + // Find the user first + const user = await User.findOne({ userId: req.user.userId }); + if (!user) { + return res.status(404).json({ error: 'User not found' }); + } + // Check if the game exists and belongs to the current user - const game = await Game.findOne({ _id: id, creator: req.user.userId }); + const game = await Game.findOne({ _id: id, creator: user._id }); if (!game) { return res.status(404).json({ error: 'Game not found or you do not have permission to edit it', @@ -247,7 +292,7 @@ router.put( if (req.file) { // Delete the old thumbnail file if (game.thumbnailUrl) { - const oldThumbnailPath = path.join( + const oldThumbnailPath = path.join( __dirname, '../../../../uploads', path.basename(game.thumbnailUrl) @@ -278,40 +323,7 @@ router.put( } ); -router.get('/:id', authenticateToken, async (req, res) => { - try { - const game = await Game.findById(req.params.id).populate( - 'creator', - 'username' - ); - if (!game) { - return res.status(404).json({ error: 'Game not found' }); - } - res.json(game); - } catch (error) { - console.error('Error fetching game:', error); - res - .status(500) - .json({ error: 'Error fetching game', details: error.message }); - } -}); -router.get('/user/:username', authenticateToken, async (req, res) => { - try { - const username = req.params.username; - const user = await User.findOne({ username: username }); - if (!user) { - return res.status(404).json({ error: 'User not found' }); - } - const games = await Game.find({ creator: user._id }).sort({ - createdAt: -1, - }); - res.json(games); - } catch (error) { - console.error('Error fetching user games:', error); - res.status(500).json({ error: 'Internal server error' }); - } -}); // Function to generate a unique asset ID function generateAssetId() { diff --git a/server/functions/api/routes/shirt.js b/server/functions/api/routes/shirt.js index c81a6ff..9751dc8 100644 --- a/server/functions/api/routes/shirt.js +++ b/server/functions/api/routes/shirt.js @@ -45,7 +45,6 @@ const authenticateToken = (req, res, next) => { return res.sendStatus(403); } req.user = { - _id: user._id, userId: user.userId }; next(); @@ -134,7 +133,7 @@ router.get('/:id', async (req, res) => { const id = req.params.id; const shirt = await Asset.findOne({ _id: id, AssetType: 'Shirt' }).populate( 'creator', - 'username' + 'username userId' ); if (!shirt) { return res.status(404).json({ error: 'Shirt not found' }); @@ -213,7 +212,7 @@ router.post( const asset = new Asset({ assetId: assetId, FileLocation: assetLocation, - creator: req.user._id, + creator: req.user.userId, AssetType: 'Image', Name: filter.clean(title), Description: filter.clean(description), @@ -252,7 +251,7 @@ router.post( const shirt = new Asset({ assetId: shirtassetId, FileLocation: shirtassetLocation, - creator: req.user._id, + creator: req.user.userId, AssetType: 'Shirt', Name: filter.clean(title), Description: filter.clean(description), @@ -323,7 +322,7 @@ router.post('/purchase/:id', authenticateToken, async (req, res) => { return res.status(404).json({ error: 'Shirt not found or not for sale' }); } - const buyer = await User.findById(req.user.userId); + const buyer = await User.findOne({ userId: req.user.userId }); if (!buyer) { return res.status(404).json({ error: 'User not found' }); } @@ -336,8 +335,7 @@ router.post('/purchase/:id', authenticateToken, async (req, res) => { return res.status(400).json({ error: 'Insufficient funds' }); } - const seller = await User.findById(shirt.creator); - if (!seller) { + const seller = await User.findOne({ userId: shirt.creator }); if (!seller) { return res.status(404).json({ error: 'Shirt creator not found' }); } @@ -441,8 +439,13 @@ router.put('/:shirtId', authenticateToken, async (req, res) => { }); } + const user = await User.findOne({ userId: req.user.userId }); + if (!user) { + return res.status(404).json({ error: 'User not found' }); + } + const updatedShirt = await Asset.findOneAndUpdate( - { _id: shirtId, creator: req.user.userId, AssetType: 'Shirt' }, + { _id: shirtId, creator: user._id, AssetType: 'Shirt' }, { Name: filter.clean(title), Description: filter.clean(description), @@ -463,30 +466,30 @@ router.put('/:shirtId', authenticateToken, async (req, res) => { console.error('Error updating shirt:', error); res .status(500) - .json({ error: 'An error occurred while updating the shirt' }); + .json({ error: 'An error occurred while updating the shirt', details: error.message }); } }); router.put('/:id', authenticateToken, async (req, res) => { try { const { id } = req.params; - const { title, description } = req.body; + const { title, description, price } = req.body; // Check if the shirt exists and belongs to the current user - const shirt = await Asset.findOne({ - _id: id, - AssetType: 'Shirt', - creator: req.user.userId, - }); + const shirt = await Asset.findOne({ _id: id, AssetType: 'Shirt' }); + if (!shirt) { - return res.status(404).json({ - error: 'Shirt not found or you do not have permission to edit it', - }); + return res.status(404).json({ error: 'Shirt not found' }); + } + + if (shirt.creator.toString() !== req.user.userId) { + return res.status(403).json({ error: 'You are not authorized to update this shirt' }); } // Update shirt details shirt.title = filter.clean(title); shirt.description = filter.clean(description); + shirt.price = price; shirt.updatedAt = new Date(); // Save the updated shirt