-
${item.Name}
-
+
+
+
+
${type.charAt(0).toUpperCase() + type.slice(1)}
+
+
+
+
${item.Name}
+
@@ -224,6 +253,40 @@ function updateCurrentlyWearing(type, item) {
container.append(itemHtml);
}
+function removeItem(type) {
+ const token = localStorage.getItem('token');
+
+ $.ajax({
+ url: '/api/avatar',
+ method: 'PUT',
+ headers: {
+ Authorization: `Bearer ${token}`,
+ 'Content-Type': 'application/json',
+ },
+ data: JSON.stringify({ type: type, itemId: null }), // Indicate unwearing
+ success: function (response) {
+ console.log('Avatar updated successfully.');
+ $(`#avatar-${type}`).attr('src', '');
+ $(`#currently-wearing [data-type="${type}"]`).remove();
+ updateWearButton(type, null, false);
+ showAlert('info', `Unwore your ${type}.`);
+ },
+ error: function (xhr, status, error) {
+ console.error('Error unwearing item:', error);
+ showAlert('danger', 'Error unwearing the item. Please try again later.');
+ },
+ });
+}
+
+function updateWearButton(type, itemId, isWearing) {
+ const wearButton = $(`.wear-item[data-type="${type}"]`);
+ wearButton.removeClass('btn-success').addClass('btn-primary').text('Wear');
+
+ if (isWearing && itemId) {
+ wearButton.removeClass('btn-primary').addClass('btn-success').text('Wearing');
+ }
+}
+
function loadUserAvatar() {
const token = localStorage.getItem('token');
$.ajax({
@@ -246,29 +309,37 @@ function loadUserAvatar() {
function saveAvatarSelection(type, itemId) {
const token = localStorage.getItem('token');
- const avatarData = {};
-
- switch (type) {
- case 'shirt':
- avatarData.shirtId = itemId;
- break;
- default:
- return;
- }
+ const avatarData = { type, itemId };
+ console.log(`Saving avatar selection: ${type}, ID: ${itemId}`);
$.ajax({
url: '/api/avatar',
method: 'PUT',
- data: JSON.stringify(avatarData),
contentType: 'application/json',
headers: {
Authorization: `Bearer ${token}`,
+ 'Content-Type': 'application/json',
},
+ data: JSON.stringify(avatarData),
success: function (response) {
- console.log('Avatar updated successfully.');
+ console.log('Avatar updated successfully:', response);
+ if (itemId) {
+ updateAvatarDisplay(type, response.avatar[`${type}Id`]);
+ updateCurrentlyWearing(type, response.avatar);
+ updateWearButton(type, itemId, true);
+ showAlert('success', `Wore your ${type} successfully.`);
+ } else {
+ $(`#avatar-${type}`).attr('src', '');
+ $(`#currently-wearing [data-type="${type}"]`).remove();
+ updateWearButton(type, null, false);
+ showAlert('info', `Unwore your ${type}.`);
+ }
},
error: function (xhr, status, error) {
console.error('Error updating avatar:', error);
+ console.error('Status:', status);
+ console.error('Response:', xhr.responseText);
+ showAlert('danger', `Error wearing ${type}. Please try again later.`);
},
});
}
@@ -303,6 +374,18 @@ function updateBodyColor(part, color) {
// to do
}
+function showAlert(type, message) {
+ const alertHtml = `
+
+
+ ${message}
+
+ `;
+ $('#avatar-container').prepend(alertHtml);
+}
+
$(document).on('click', '.remove-item', function() {
const type = $(this).data('type');
removeItem(type);
diff --git a/client/js/user-profile.js b/client/js/user-profile.js
index d1f1557..7f921e8 100644
--- a/client/js/user-profile.js
+++ b/client/js/user-profile.js
@@ -550,10 +550,9 @@ $(document).ready(function () {
// Load user's shirts
loadUserShirts(user._id);
- // Initialize Bootstrap tabs
+ // Bootstrap tabs
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
- // You can add logic here to load items dynamically if needed
- // console.log('Tab switched to: ' + $(e.target).attr('href'));
+
});
}
@@ -565,7 +564,7 @@ $(document).ready(function () {
Authorization: `Bearer ${localStorage.getItem('token')}`,
},
success: function (shirts) {
- displayUserShirts(shirts);
+ displayUserShirts(shirts, userId);
},
error: function (xhr, status, error) {
console.error('Error fetching user shirts:', error);
@@ -576,7 +575,7 @@ $(document).ready(function () {
});
}
- function displayUserShirts(shirts) {
+ function displayUserShirts(shirts, userId) {
const shirtsContainer = $('#user-shirts');
shirtsContainer.empty();
@@ -590,7 +589,8 @@ $(document).ready(function () {
shirt.Name,
shirt.ThumbnailLocation,
shirt.creator ? shirt.creator.username : 'Unknown',
- shirt.Price
+ shirt.Price,
+ shirt.creator && shirt.creator._id === userId ? 'Created' : 'Owned'
);
shirtsContainer.append(shirtHtml);
});
diff --git a/server/functions/api/routes/avatar.js b/server/functions/api/routes/avatar.js
index f92f409..7b11c98 100644
--- a/server/functions/api/routes/avatar.js
+++ b/server/functions/api/routes/avatar.js
@@ -3,6 +3,7 @@ const router = express.Router();
const authenticateToken = require('../middleware/authenticateToken');
const User = require('../models/User');
const mongoose = require('mongoose');
+const Asset = require('../models/Asset');
// Get current avatar
router.get('/', authenticateToken, async (req, res) => {
@@ -26,35 +27,72 @@ router.get('/', authenticateToken, async (req, res) => {
// Update avatar
router.put('/', authenticateToken, async (req, res) => {
try {
- const { shirtId } = req.body;
+ const { type, itemId } = req.body;
+ console.log('Updating avatar:', { userId: req.user.userId, type, itemId });
- const user = await User.findOne({ userId: req.user.userId });
+ if (!type || !['shirt', 'pants', 'hat'].includes(type)) {
+ console.error('Invalid or missing item type:', type);
+ return res.status(400).json({ error: 'Invalid or missing item type' });
+ }
+
+ const user = await User.findOne({ userId: req.user.userId }).populate('inventory');
+
if (!user) {
console.error('User not found for userId:', req.user.userId);
return res.status(404).json({ error: 'User not found' });
}
- if (shirtId) {
- if (!mongoose.Types.ObjectId.isValid(shirtId)) {
- console.error('Invalid shirt ID:', shirtId);
- return res.status(400).json({ error: 'Invalid shirt ID' });
- }
+ if (!user.avatar) {
+ user.avatar = {};
+ }
+
+ console.log('User inventory:', user.inventory.map(item => ({ id: item._id.toString(), type: item.AssetType })));
+
- // Check if the shirt is in inventory
- if (!user.inventory.includes(shirtId)) {
- console.error('Shirt not in user inventory:', shirtId);
- return res.status(400).json({ error: 'Shirt not in user inventory' });
- }
+ switch (type) {
+ case 'shirt':
+ if (itemId) {
+ if (!mongoose.Types.ObjectId.isValid(itemId)) {
+ console.error('Invalid shirt ID:', itemId);
+ return res.status(400).json({ error: 'Invalid shirt ID' });
+ }
- user.avatar.shirtId = shirtId;
+ console.log('Checking inventory for shirt:', itemId);
+
+ const inventoryItem = user.inventory.find(item =>
+ item._id.toString() === itemId && item.AssetType === 'Shirt'
+ );
+
+ const createdShirt = await Asset.findOne({
+ _id: itemId,
+ creator: user._id,
+ AssetType: 'Shirt'
+ });
+
+ if (!inventoryItem && !createdShirt) {
+ console.error('Shirt not in user inventory or not created by user:', itemId);
+ return res.status(400).json({ error: 'Shirt not in user inventory or not created by u' });
+ }
+
+ console.log('Setting shirt:', itemId);
+ user.avatar.shirt = inventoryItem;
+ } else {
+ console.log('Unwearing shirt');
+ user.avatar.shirt = null;
+ }
+ break;
+ // cases for pants and hats can be added here later
+ default:
+ console.error('Unsupported item type:', type);
+ return res.status(400).json({ error: 'Unsupported item type' });
}
await user.save();
- console.log('Avatar updated successfully for userId:', req.user.userId);
- res.json({ message: 'Avatar updated successfully' });
+ console.log('Avatar updated successfully for userId:', req.user.userId, 'New avatar:', user.avatar);
+ res.json({ message: 'Avatar updated successfully', avatar: user.avatar });
} catch (error) {
console.error('Error updating avatar:', error);
- res.status(500).json({ error: 'Internal server error', details: error.message });
+ res.status(500).json({ error: 'Internal server error', details: error.message, stack: error.stack });
}
});
diff --git a/server/functions/api/routes/shirt.js b/server/functions/api/routes/shirt.js
index 78b7794..c090a4d 100644
--- a/server/functions/api/routes/shirt.js
+++ b/server/functions/api/routes/shirt.js
@@ -274,7 +274,10 @@ router.post(
await thumbnailQueue.addToQueue(shirtassetId, 'Shirt');
await User.findByIdAndUpdate(req.user._id, {
- $push: { shirts: shirt._id },
+ $push: {
+ shirts: shirt._id,
+ inventory: shirt._id
+ },
});
res.status(201).json({ shirtId: shirt._id, assetId: shirt.assetId });