![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/.cursor-server/data/User/History/-7bdcb5ab/ |
<?php
session_start();
require_once 'config/database.php';
// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
header('Location: /auth/login.php');
exit;
}
$pdo = getDBConnection();
// Get user info with profile data - explicitly select name and email like account_settings.php
$stmt = $pdo->prepare("
SELECT
u.id,
u.name,
u.email,
u.credits,
COALESCE(u.plan, 'free') as plan,
u.created_at,
up.bio,
up.location,
up.website,
up.social_links,
up.profile_image,
up.paypal_me_username,
up.music_style,
up.genres,
up.influences,
up.equipment,
up.artist_statement,
up.artist_highlights,
up.achievements
FROM users u
LEFT JOIN user_profiles up ON u.id = up.user_id
WHERE u.id = ?
");
$stmt->execute([$_SESSION['user_id']]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
// Ensure user data exists
if (!$user || !is_array($user)) {
error_log("ERROR: Failed to fetch user data for user ID: " . $_SESSION['user_id']);
header('Location: /auth/login.php');
exit;
}
// Ensure required fields exist in the user array
if (!isset($user['email']) || !isset($user['name'])) {
error_log("ERROR: User data missing required fields. User ID: " . $_SESSION['user_id']);
// Use session values as fallback
if (!isset($user['email'])) {
$user['email'] = $_SESSION['user_email'] ?? '';
}
if (!isset($user['name'])) {
$user['name'] = $_SESSION['user_name'] ?? '';
}
}
// Set page variables for header
$page_title = 'Profile Settings - SoundStudioPro';
$page_description = 'Customize your profile, color scheme, and preferences.';
// Include header
include 'includes/header.php';
?>
<style>
.settings-container {
max-width: 80rem;
margin: 0 auto;
padding: 4rem 0;
}
.settings-section {
background: var(--bg-card);
border-radius: 20px;
padding: 3rem;
margin-bottom: 3rem;
box-shadow: var(--shadow-light);
border: 1px solid var(--border-light);
}
.section-title {
font-size: 2.4rem;
font-weight: 700;
margin-bottom: 2rem;
background: var(--primary-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
display: flex;
align-items: center;
gap: 1rem;
}
.form-group {
margin-bottom: 2rem;
}
.form-label {
display: block;
font-size: 1.6rem;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 1rem;
}
.form-input {
background: var(--bg-secondary);
color: var(--text-primary);
border: 1px solid var(--border-light);
padding: 1rem 1.5rem;
border-radius: 10px;
font-size: 1.4rem;
width: 100%;
transition: all 0.3s ease;
}
.form-help {
display: block;
font-size: 1.2rem;
color: var(--text-secondary);
margin-top: 0.5rem;
}
.form-help a {
color: var(--primary-color);
text-decoration: none;
}
.form-help a:hover {
text-decoration: underline;
}
.url-input-group {
display: flex;
align-items: center;
gap: 0.5rem;
}
.url-prefix {
background: var(--bg-secondary);
padding: 1rem 1.5rem;
border: 1px solid var(--border-light);
border-radius: 10px 0 0 10px;
color: var(--text-secondary);
font-size: 1.4rem;
white-space: nowrap;
}
.url-input-group .url-input {
border-radius: 0 10px 10px 0;
border-left: none;
}
.form-input:focus {
outline: none;
border-color: var(--primary-gradient);
box-shadow: 0 0 0 3px var(--shadow-light);
}
.save-btn {
background: var(--primary-gradient);
color: var(--text-primary);
border: none;
padding: 1.2rem 3rem;
border-radius: 12px;
font-size: 1.6rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: var(--shadow-light);
}
.save-btn:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-medium);
}
/* Profile Image Upload Styles */
.profile-image-upload {
display: flex;
align-items: center;
gap: 2rem;
margin-bottom: 2rem;
}
.current-image {
width: 8rem;
height: 8rem;
border-radius: 50%;
overflow: hidden;
background: var(--primary-gradient);
display: flex;
align-items: center;
justify-content: center;
border: 3px solid var(--border-light);
}
.current-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
.default-profile-image {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 3rem;
font-weight: 700;
}
.upload-controls {
display: flex;
flex-direction: column;
gap: 1rem;
}
.upload-btn {
background: var(--primary-gradient);
color: white;
border: none;
padding: 1rem 2rem;
border-radius: 12px;
font-size: 1.4rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.5rem;
text-decoration: none;
}
.upload-btn:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-medium);
}
.remove-btn {
background: linear-gradient(135deg, #dc3545, #c82333);
color: white;
border: none;
padding: 1rem 2rem;
border-radius: 12px;
font-size: 1.4rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.5rem;
}
.remove-btn:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-medium);
}
/* Enhanced Profile Settings Styles */
.genre-selection {
margin-top: 1rem;
}
.genre-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 1rem;
margin-top: 1rem;
}
.genre-checkbox {
display: flex;
align-items: center;
gap: 0.8rem;
padding: 1rem;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
}
.genre-checkbox:hover {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(102, 126, 234, 0.3);
}
.genre-checkbox input[type="checkbox"] {
width: 1.8rem;
height: 1.8rem;
accent-color: #667eea;
}
.genre-label {
font-size: 1.4rem;
color: var(--text-primary);
font-weight: 500;
}
.highlights-input, .achievements-input {
margin-top: 1rem;
}
.highlight-inputs, .achievement-inputs {
display: flex;
flex-direction: column;
gap: 1rem;
}
.highlight-input, .achievement-input {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
color: var(--text-primary);
transition: all 0.3s ease;
}
.highlight-input:focus, .achievement-input:focus {
outline: none;
border-color: var(--primary-gradient);
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2);
}
</style>
<div class="settings-container">
<div class="settings-section">
<h2 class="section-title">
<i class="fas fa-user-edit"></i>
Profile Information
</h2>
<form id="profileForm">
<!-- Profile Image Upload -->
<div class="form-group">
<label class="form-label">Profile Image</label>
<div class="profile-image-upload">
<div class="current-image">
<?php if (!empty($user['profile_image'])): ?>
<img src="<?= htmlspecialchars($user['profile_image']) ?>" alt="<?= htmlspecialchars(ucwords(strtolower($user['name'] ?? ''))) ?>" id="currentProfileImage">
<?php else: ?>
<div class="default-profile-image" id="defaultProfileImage"><?= substr(htmlspecialchars(ucwords(strtolower($user['name'] ?? ''))), 0, 1) ?></div>
<?php endif; ?>
</div>
<div class="upload-controls">
<label for="profileImageUpload" class="upload-btn">
<i class="fas fa-camera"></i>
<?= !empty($user['profile_image']) ? 'Change Photo' : 'Upload Photo' ?>
</label>
<input type="file" id="profileImageUpload" accept="image/*" style="display: none;">
<?php if (!empty($user['profile_image'])): ?>
<button type="button" class="remove-btn" onclick="removeProfileImage()">
<i class="fas fa-trash"></i>
Remove
</button>
<?php endif; ?>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label">Artist Name <span style="color: #ef4444;">*</span></label>
<?php
$name_value = !empty($user['name']) ? trim($user['name']) : (isset($_SESSION['user_name']) ? trim($_SESSION['user_name']) : '');
?>
<input type="text" class="form-input" name="name" id="profile_name" value="<?= htmlspecialchars($name_value, ENT_QUOTES, 'UTF-8') ?>" placeholder="Your artist name" required>
</div>
<!-- Genre Selection -->
<div class="form-group">
<label class="form-label">Music Genres</label>
<div class="genre-selection">
<?php
// Ensure genres are properly decoded - handle null, empty string, or invalid JSON
$genresJson = $user['genres'] ?? null;
if (empty($genresJson) || $genresJson === 'null' || $genresJson === 'NULL') {
$userGenres = [];
} else {
$decoded = json_decode($genresJson, true);
$userGenres = is_array($decoded) ? $decoded : [];
}
$allGenres = ['House', 'Techno', 'Trance', 'Dubstep', 'Drum & Bass', 'Ambient', 'Chillout', 'Progressive', 'Electro', 'Hardstyle', 'Psytrance', 'Downtempo', 'Breaks', 'Garage', 'Jungle', 'IDM', 'Experimental', 'Synthwave', 'Future Bass', 'Trap'];
?>
<div class="genre-grid">
<?php foreach ($allGenres as $genre): ?>
<label class="genre-checkbox">
<input type="checkbox" name="genres[]" value="<?= htmlspecialchars($genre) ?>"
<?= in_array($genre, $userGenres, true) ? 'checked' : '' ?>>
<span class="genre-label"><?= htmlspecialchars($genre) ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label">Music Style</label>
<textarea class="form-input" name="music_style" rows="3" placeholder="Describe your unique music style, what makes you special..."><?= htmlspecialchars($user['music_style'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label class="form-label">Artist Highlights</label>
<div class="highlights-input">
<div class="highlight-inputs">
<?php
$highlights = json_decode($user['artist_highlights'] ?? '[]', true);
for ($i = 0; $i < 5; $i++):
?>
<input type="text" class="form-input highlight-input" name="artist_highlights[]"
value="<?= htmlspecialchars($highlights[$i] ?? '') ?>"
placeholder="Add a highlight (e.g., 'Featured on BBC Radio 1')">
<?php endfor; ?>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label">Musical Influences</label>
<textarea class="form-input" name="influences" rows="3" placeholder="Who inspires your music? Artists, genres, life experiences..."><?= htmlspecialchars($user['influences'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label class="form-label">Equipment & Setup</label>
<textarea class="form-input" name="equipment" rows="3" placeholder="What equipment do you use? Software, hardware, instruments..."><?= htmlspecialchars($user['equipment'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label class="form-label">Achievements</label>
<div class="achievements-input">
<div class="achievement-inputs">
<?php
$achievements = json_decode($user['achievements'] ?? '[]', true);
for ($i = 0; $i < 5; $i++):
?>
<input type="text" class="form-input achievement-input" name="achievements[]"
value="<?= htmlspecialchars($achievements[$i] ?? '') ?>"
placeholder="Add an achievement (e.g., 'Top 10 on Beatport')">
<?php endfor; ?>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label">Artist Statement</label>
<textarea class="form-input" name="artist_statement" rows="3" placeholder="Your personal mission statement as an artist..."><?= htmlspecialchars($user['artist_statement'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label class="form-label">Bio</label>
<textarea class="form-input" name="bio" rows="4" placeholder="Tell us about your musical journey and spiritual inspiration..."><?= htmlspecialchars($user['bio'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label class="form-label">Location</label>
<input type="text" class="form-input" name="location" value="<?= htmlspecialchars($user['location'] ?? '') ?>" placeholder="City, Country">
</div>
<div class="form-group">
<label class="form-label">Website</label>
<input type="url" class="form-input" name="website" value="<?= htmlspecialchars($user['website'] ?? '') ?>" placeholder="https://yourwebsite.com">
</div>
<div class="form-group">
<label class="form-label">PayPal.Me Username</label>
<div class="url-input-group">
<span class="url-prefix">paypal.me/</span>
<input type="text" class="form-input url-input" name="paypal_me_username"
value="<?= htmlspecialchars($user['paypal_me_username'] ?? '') ?>"
placeholder="yourusername"
pattern="[a-zA-Z0-9-]+"
title="Only letters, numbers, and hyphens allowed"
style="text-transform: lowercase;">
</div>
<small class="form-help">Create your PayPal.Me link at <a href="https://www.paypal.com/paypalme/" target="_blank" rel="noopener">paypal.com/paypalme</a></small>
</div>
<div class="form-group">
<label class="form-label">Email</label>
<?php
$email_value = !empty($user['email']) ? trim($user['email']) : (isset($_SESSION['user_email']) ? trim($_SESSION['user_email']) : '');
?>
<input type="email" class="form-input" name="email" id="profile_email" value="<?= htmlspecialchars($email_value, ENT_QUOTES, 'UTF-8') ?>" placeholder="your@email.com" required>
</div>
<button type="submit" class="save-btn">
<i class="fas fa-save"></i>
Save Changes
</button>
</form>
</div>
</div>
<script>
function showNotification(message, type = 'info') {
// Create notification element
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
top: 100px;
right: 20px;
background: var(--bg-card);
color: var(--text-primary);
padding: 1.5rem 2rem;
border-radius: 12px;
box-shadow: var(--shadow-medium);
border: 2px solid var(--border-medium);
z-index: 10000;
font-size: 1.4rem;
font-weight: 500;
transform: translateX(100%);
transition: transform 0.3s ease;
`;
notification.textContent = message;
document.body.appendChild(notification);
// Animate in
setTimeout(() => {
notification.style.transform = 'translateX(0)';
}, 100);
// Remove after 3 seconds
setTimeout(() => {
notification.style.transform = 'translateX(100%)';
setTimeout(() => {
document.body.removeChild(notification);
}, 300);
}, 3000);
}
// Handle profile form submission
// Profile image upload functionality
const profileImageUpload = document.getElementById('profileImageUpload');
if (profileImageUpload) {
profileImageUpload.addEventListener('change', function(e) {
const file = e.target.files[0];
if (!file) return;
// Validate file type
if (!file.type.startsWith('image/')) {
showNotification('Please select a valid image file.', 'error');
return;
}
// Validate file size (5MB max)
if (file.size > 5 * 1024 * 1024) {
showNotification('File size must be less than 5MB.', 'error');
return;
}
uploadProfileImage(file);
});
}
function uploadProfileImage(file) {
const formData = new FormData();
formData.append('profile_image', file);
// Show loading state
const currentImage = document.getElementById('currentProfileImage');
const defaultImage = document.getElementById('defaultProfileImage');
const uploadBtn = document.querySelector('.upload-btn');
if (currentImage) {
currentImage.style.opacity = '0.5';
}
if (defaultImage) {
defaultImage.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
}
if (uploadBtn) {
uploadBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Uploading...';
uploadBtn.disabled = true;
}
fetch('/api/upload_profile_image.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
updateProfileImageDisplay(data.image_url);
showNotification('Profile image uploaded successfully!', 'success');
} else {
showNotification('Error uploading image: ' + (data.error || 'Unknown error'), 'error');
restoreOriginalState();
}
})
.catch(error => {
console.error('Error:', error);
showNotification('Error uploading image. Please try again.', 'error');
restoreOriginalState();
});
}
function updateProfileImageDisplay(imageUrl) {
const currentImage = document.getElementById('currentProfileImage');
const defaultImage = document.getElementById('defaultProfileImage');
const uploadBtn = document.querySelector('.upload-btn');
const removeBtn = document.querySelector('.remove-btn');
if (currentImage) {
currentImage.src = imageUrl;
currentImage.style.opacity = '1';
} else if (defaultImage) {
// Replace default image with actual image
defaultImage.outerHTML = `<img src="${imageUrl}" alt="Profile" id="currentProfileImage">`;
}
if (uploadBtn) {
uploadBtn.innerHTML = '<i class="fas fa-camera"></i> Change Photo';
uploadBtn.disabled = false;
}
// Add remove button if it doesn't exist
if (!removeBtn) {
const uploadControls = document.querySelector('.upload-controls');
const newRemoveBtn = document.createElement('button');
newRemoveBtn.type = 'button';
newRemoveBtn.className = 'remove-btn';
newRemoveBtn.onclick = removeProfileImage;
newRemoveBtn.innerHTML = '<i class="fas fa-trash"></i> Remove';
uploadControls.appendChild(newRemoveBtn);
}
}
function removeProfileImage() {
if (confirm('Are you sure you want to remove your profile image?')) {
fetch('/api/update_profile.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: document.querySelector('input[name="name"]').value,
email: document.querySelector('input[name="email"]').value,
bio: document.querySelector('textarea[name="bio"]').value,
location: document.querySelector('input[name="location"]').value,
website: document.querySelector('input[name="website"]').value,
profile_image: ''
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
const currentImage = document.getElementById('currentProfileImage');
const defaultImage = document.getElementById('defaultProfileImage');
const removeBtn = document.querySelector('.remove-btn');
const uploadBtn = document.querySelector('.upload-btn');
const userName = document.querySelector('input[name="name"]').value;
if (currentImage) {
currentImage.outerHTML = `<div class="default-profile-image" id="defaultProfileImage">${userName.charAt(0).toUpperCase()}</div>`;
}
if (removeBtn) {
removeBtn.remove();
}
if (uploadBtn) {
uploadBtn.innerHTML = '<i class="fas fa-camera"></i> Upload Photo';
}
showNotification('Profile image removed successfully!', 'success');
} else {
showNotification('Error removing image: ' + (data.error || 'Unknown error'), 'error');
}
})
.catch(error => {
console.error('Error:', error);
showNotification('Error removing image. Please try again.', 'error');
});
}
}
function restoreOriginalState() {
const currentImage = document.getElementById('currentProfileImage');
const defaultImage = document.getElementById('defaultProfileImage');
const uploadBtn = document.querySelector('.upload-btn');
const userName = document.querySelector('input[name="name"]').value;
if (currentImage) {
currentImage.style.opacity = '1';
}
if (defaultImage) {
defaultImage.innerHTML = userName.charAt(0).toUpperCase();
}
if (uploadBtn) {
uploadBtn.innerHTML = '<i class="fas fa-camera"></i> Change Photo';
uploadBtn.disabled = false;
}
}
document.getElementById('profileForm').addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
// Handle arrays properly
const data = {};
for (let [key, value] of formData.entries()) {
if (key.endsWith('[]')) {
const arrayKey = key.slice(0, -2);
if (!data[arrayKey]) {
data[arrayKey] = [];
}
if (value.trim()) {
data[arrayKey].push(value.trim());
}
} else {
data[key] = value.trim();
}
}
// Ensure name is always sent (required field)
if (!data.name || !data.name.trim()) {
const nameInput = document.querySelector('input[name="name"]');
if (nameInput && nameInput.value.trim()) {
data.name = nameInput.value.trim();
} else {
showNotification('Artist name is required', 'error');
const saveBtn = document.querySelector('.save-btn');
saveBtn.innerHTML = '<i class="fas fa-save"></i> Save Changes';
saveBtn.disabled = false;
return;
}
}
try {
const saveBtn = document.querySelector('.save-btn');
const originalText = saveBtn.innerHTML;
saveBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Saving...';
saveBtn.disabled = true;
const response = await fetch('/api/update_profile.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
const result = await response.json();
if (response.ok && result.success) {
showNotification('Profile updated successfully!', 'success');
// Reload page after a short delay to show updated data
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
const errorMsg = result.error || 'Error updating profile. Please try again.';
showNotification(errorMsg, 'error');
saveBtn.innerHTML = originalText;
saveBtn.disabled = false;
}
} catch (error) {
console.error('Profile update error:', error);
showNotification('Error updating profile. Please try again.', 'error');
const saveBtn = document.querySelector('.save-btn');
saveBtn.innerHTML = '<i class="fas fa-save"></i> Save Changes';
saveBtn.disabled = false;
}
});
</script>
<?php include 'includes/footer.php'; ?>