![]() 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/domains/soundstudiopro.com/private_html/ |
<?php
session_start();
require_once 'config/database.php';
require_once 'includes/translations.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,
COALESCE(up.paypal_me_username, '') as 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);
// DEBUG: Log raw data from database
error_log("Profile Settings - Raw paypal_me_username from query: " . var_export($user['paypal_me_username'] ?? 'NOT SET', true));
error_log("Profile Settings - Type: " . gettype($user['paypal_me_username'] ?? 'NOT SET'));
// Handle JSON columns - MySQL returns JSON as strings by default
// Keep genres as-is from database (don't normalize here, we'll handle it in the form section)
// This prevents double-processing issues
// Ensure paypal_me_username is properly set (handle null and empty)
// Convert null to empty string for consistent handling
if (!isset($user['paypal_me_username'])) {
$user['paypal_me_username'] = '';
} elseif ($user['paypal_me_username'] === null || $user['paypal_me_username'] === false) {
$user['paypal_me_username'] = '';
} else {
// Ensure it's a string and trimmed - don't trim if it's already empty
$user['paypal_me_username'] = is_string($user['paypal_me_username']) ? trim($user['paypal_me_username']) : (string)$user['paypal_me_username'];
}
// DEBUG: Log what we got from database after normalization
error_log("Profile Settings - PayPal.Me username after normalization: " . var_export($user['paypal_me_username'], true));
error_log("Profile Settings - PayPal.Me username length: " . strlen($user['paypal_me_username']));
// 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 = t('profile_settings.page_title') ?? 'Profile Settings - SoundStudioPro';
$page_description = t('profile_settings.page_description') ?? 'Customize your profile information.';
// 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>
<?= t('profile_settings.profile_information') ?? 'Profile Information' ?>
</h2>
<form id="profileForm">
<!-- Profile Image Upload -->
<div class="form-group">
<label class="form-label"><?= t('profile_settings.profile_image') ?? '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']) ? (t('profile_settings.change_photo') ?? 'Change Photo') : (t('profile_settings.upload_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>
<?= t('profile_settings.remove') ?? 'Remove' ?>
</button>
<?php endif; ?>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label"><?= t('profile_settings.artist_name') ?? '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="<?= t('profile_settings.artist_name_placeholder') ?? 'Your artist name' ?>" required>
</div>
<!-- Genre Selection -->
<div class="form-group">
<label class="form-label"><?= t('profile_settings.music_genres') ?? 'Music Genres' ?></label>
<div class="genre-selection">
<?php
// Try multiple ways to fetch genres
$userGenres = [];
$genresRaw = null;
// Method 1: From the JOIN query result
if (!empty($user['genres']) && $user['genres'] !== 'NULL' && $user['genres'] !== null) {
$genresRaw = $user['genres'];
}
// Method 2: Direct query if not found in JOIN
if (empty($genresRaw) || $genresRaw === 'NULL' || $genresRaw === null) {
$directStmt = $pdo->prepare("SELECT genres FROM user_profiles WHERE user_id = ?");
$directStmt->execute([$_SESSION['user_id']]);
$directResult = $directStmt->fetch(PDO::FETCH_ASSOC);
if ($directResult && !empty($directResult['genres']) && $directResult['genres'] !== 'NULL') {
$genresRaw = $directResult['genres'];
}
}
// Method 3: Try JSON_EXTRACT if it's a JSON column
if (empty($genresRaw) || $genresRaw === 'NULL' || $genresRaw === null) {
$jsonStmt = $pdo->prepare("SELECT JSON_EXTRACT(genres, '$') as genres FROM user_profiles WHERE user_id = ?");
$jsonStmt->execute([$_SESSION['user_id']]);
$jsonResult = $jsonStmt->fetch(PDO::FETCH_ASSOC);
if ($jsonResult && !empty($jsonResult['genres']) && $jsonResult['genres'] !== 'NULL') {
$genresRaw = $jsonResult['genres'];
}
}
// Decode the genres
if (!empty($genresRaw) && $genresRaw !== 'NULL' && $genresRaw !== null) {
if (is_array($genresRaw)) {
$userGenres = $genresRaw;
} elseif (is_string($genresRaw)) {
$decoded = json_decode($genresRaw, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
$userGenres = $decoded;
}
}
}
// Ensure it's an array
if (!is_array($userGenres)) {
$userGenres = [];
}
// Normalize user genres for comparison (trim and lowercase)
$userGenresNormalized = [];
foreach ($userGenres as $genre) {
if (!empty(trim($genre))) {
$normalized = strtolower(preg_replace('/[\s\-_]+/', ' ', trim($genre)));
$userGenresNormalized[] = $normalized;
}
}
// Comprehensive genre list - no duplicates, includes all popular genres
$allGenres = [
// Electronic/Dance
'Electronic', 'EDM', 'House', 'Deep House', 'Tech House', 'Progressive House', 'Future House',
'Techno', 'Deep Techno', 'Minimal Techno', 'Hard Techno',
'Trance', 'Progressive Trance', 'Uplifting Trance', 'Psytrance',
'Dubstep', 'Brostep', 'Melodic Dubstep',
'Drum & Bass', 'Liquid D&B', 'Neurofunk',
'Ambient', 'Chillout', 'Downtempo', 'Lounge', 'Lofi',
'Progressive', 'Electro', 'Hardstyle', 'Breaks', 'Garage', 'Jungle',
'IDM', 'Experimental', 'Synthwave', 'Future Bass', 'Trap',
// Hip Hop/Rap
'Hip Hop', 'Rap', 'R&B', 'Soul', 'Funk',
// Rock/Metal
'Rock', 'Indie', 'Indie Rock', 'Alternative', 'Alternative Rock', 'Metal', 'Punk',
// Pop
'Pop', 'Electronic Pop', 'Indie Pop',
// Other
'Jazz', 'Fusion', 'Latin', 'Reggae', 'World', 'Country', 'Blues', 'Disco',
'Classical', 'Orchestral', 'Cinematic', 'Folk', 'Acoustic'
];
// Remove duplicates using normalized comparison (handles "Hip Hop" vs "Hip-Hop", "Drum & Bass" vs "Drum and Bass")
$uniqueGenres = [];
$seenNormalized = [];
foreach ($allGenres as $genre) {
$normalized = strtolower(preg_replace('/[\s\-_&]+/', ' ', trim($genre)));
if (!in_array($normalized, $seenNormalized, true)) {
$uniqueGenres[] = $genre;
$seenNormalized[] = $normalized;
}
}
$allGenres = $uniqueGenres;
sort($allGenres);
?>
<div class="genre-grid">
<?php
// First, show all standard genres with checkboxes
foreach ($allGenres as $genre):
// Normalize genre name for comparison (same as user genres)
$genreNormalized = strtolower(preg_replace('/[\s\-_]+/', ' ', trim($genre)));
// Simple check: is this normalized genre in the user's normalized genres array?
$isChecked = in_array($genreNormalized, $userGenresNormalized, true);
?>
<label class="genre-checkbox">
<input type="checkbox" name="genres[]" value="<?= htmlspecialchars($genre) ?>"
<?= $isChecked ? 'checked' : '' ?>>
<span class="genre-label"><?= htmlspecialchars($genre) ?></span>
</label>
<?php endforeach; ?>
<?php
// Also show any user genres that aren't in the standard list
$standardGenresNormalized = array_map(function($g) {
return preg_replace('/[\s\-_]+/', ' ', strtolower(trim($g)));
}, $allGenres);
$userGenresNotInList = [];
foreach ($userGenres as $userGenre) {
$userGenreNormalized = preg_replace('/[\s\-_]+/', ' ', strtolower(trim($userGenre)));
$found = false;
foreach ($standardGenresNormalized as $stdGenreNorm) {
if ($userGenreNormalized === $stdGenreNorm) {
$found = true;
break;
}
}
if (!$found) {
$userGenresNotInList[] = $userGenre;
}
}
// Show user's custom genres that aren't in the standard list
if (!empty($userGenresNotInList)):
foreach ($userGenresNotInList as $customGenre):
?>
<label class="genre-checkbox" style="opacity: 0.8;">
<input type="checkbox" name="genres[]" value="<?= htmlspecialchars($customGenre) ?>" checked>
<span class="genre-label"><?= htmlspecialchars($customGenre) ?> <small>(custom)</small></span>
</label>
<?php
endforeach;
endif;
?>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label"><?= t('profile_settings.music_style') ?? 'Music Style' ?></label>
<textarea class="form-input" name="music_style" rows="3" placeholder="<?= t('profile_settings.music_style_placeholder') ?? 'Describe your unique music style, what makes you special...' ?>"><?= htmlspecialchars($user['music_style'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label class="form-label"><?= t('profile_settings.artist_highlights') ?? '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="<?= t('profile_settings.highlight_placeholder') ?? 'Add a highlight (e.g., \'Featured on BBC Radio 1\')' ?>">
<?php endfor; ?>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label"><?= t('profile_settings.musical_influences') ?? 'Musical Influences' ?></label>
<textarea class="form-input" name="influences" rows="3" placeholder="<?= t('profile_settings.influences_placeholder') ?? 'Who inspires your music? Artists, genres, life experiences...' ?>"><?= htmlspecialchars($user['influences'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label class="form-label"><?= t('profile_settings.equipment_setup') ?? 'Equipment & Setup' ?></label>
<textarea class="form-input" name="equipment" rows="3" placeholder="<?= t('profile_settings.equipment_placeholder') ?? 'What equipment do you use? Software, hardware, instruments...' ?>"><?= htmlspecialchars($user['equipment'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label class="form-label"><?= t('profile_settings.achievements') ?? '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="<?= t('profile_settings.achievement_placeholder') ?? 'Add an achievement (e.g., \'Top 10 on Beatport\')' ?>">
<?php endfor; ?>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label"><?= t('profile_settings.artist_statement') ?? 'Artist Statement' ?></label>
<textarea class="form-input" name="artist_statement" rows="3" placeholder="<?= t('profile_settings.artist_statement_placeholder') ?? 'Your personal mission statement as an artist...' ?>"><?= htmlspecialchars($user['artist_statement'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label class="form-label"><?= t('profile_settings.bio') ?? 'Bio' ?></label>
<textarea class="form-input" name="bio" rows="4" placeholder="<?= t('profile_settings.bio_placeholder') ?? 'Tell us about your musical journey and spiritual inspiration...' ?>"><?= htmlspecialchars($user['bio'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label class="form-label"><?= t('profile_settings.location') ?? 'Location' ?></label>
<input type="text" class="form-input" name="location" value="<?= htmlspecialchars($user['location'] ?? '') ?>" placeholder="<?= t('profile_settings.location_placeholder') ?? 'City, Country' ?>">
</div>
<div class="form-group">
<label class="form-label"><?= t('profile_settings.website') ?? 'Website' ?></label>
<input type="url" class="form-input" name="website" value="<?= htmlspecialchars($user['website'] ?? '') ?>" placeholder="<?= t('profile_settings.website_placeholder') ?? 'https://yourwebsite.com' ?>">
</div>
<div class="form-group">
<label class="form-label"><?= t('profile_settings.paypal_me_username') ?? 'PayPal.Me Username' ?></label>
<div class="url-input-group">
<span class="url-prefix">paypal.me/</span>
<?php
// Try multiple ways to fetch PayPal.Me username (same approach as genres)
$paypal_username = '';
// Method 1: From the JOIN query result
if (!empty($user['paypal_me_username']) && $user['paypal_me_username'] !== 'NULL' && $user['paypal_me_username'] !== null) {
$paypal_username = trim($user['paypal_me_username']);
}
// Method 2: Direct query if not found in JOIN
if (empty($paypal_username)) {
$directStmt = $pdo->prepare("SELECT paypal_me_username FROM user_profiles WHERE user_id = ?");
$directStmt->execute([$_SESSION['user_id']]);
$directResult = $directStmt->fetch(PDO::FETCH_ASSOC);
if ($directResult && !empty($directResult['paypal_me_username']) && $directResult['paypal_me_username'] !== 'NULL') {
$paypal_username = trim($directResult['paypal_me_username']);
}
}
// Ensure it's a string and lowercase
if (!empty($paypal_username)) {
$paypal_username = strtolower(trim($paypal_username));
} else {
$paypal_username = '';
}
?>
<input type="text" class="form-input url-input" name="paypal_me_username"
value="<?= htmlspecialchars($paypal_username, ENT_QUOTES, 'UTF-8') ?>"
placeholder="<?= t('profile_settings.paypal_me_placeholder') ?? 'yourusername' ?>"
pattern="[a-zA-Z0-9-]+"
title="<?= t('profile_settings.paypal_me_title') ?? 'Only letters, numbers, and hyphens allowed' ?>"
style="text-transform: lowercase;">
</div>
<small class="form-help"><?= t('profile_settings.paypal_me_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"><?= t('profile_settings.email') ?? '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="<?= t('profile_settings.email_placeholder') ?? 'your@email.com' ?>" required>
</div>
<button type="submit" class="save-btn">
<i class="fas fa-save"></i>
<?= t('profile_settings.save_changes') ?? 'Save Changes' ?>
</button>
</form>
</div>
</div>
<script>
// Translation variables for JavaScript
const profileSettingsTranslations = {
removeImageConfirm: <?= json_encode(t('profile_settings.remove_image_confirm') ?? 'Are you sure you want to remove your profile image?') ?>,
uploadPhoto: <?= json_encode(t('profile_settings.upload_photo') ?? 'Upload Photo') ?>,
changePhoto: <?= json_encode(t('profile_settings.change_photo') ?? 'Change Photo') ?>,
imageRemovedSuccess: <?= json_encode(t('profile_settings.image_removed_success') ?? 'Profile image removed successfully!') ?>,
imageRemoveError: <?= json_encode(t('profile_settings.image_remove_error') ?? 'Error removing image. Please try again.') ?>,
artistNameRequired: <?= json_encode(t('profile_settings.artist_name_required') ?? 'Artist name is required') ?>,
saving: <?= json_encode(t('profile_settings.saving') ?? 'Saving...') ?>,
saveChanges: <?= json_encode(t('profile_settings.save_changes') ?? 'Save Changes') ?>,
profileUpdatedSuccess: <?= json_encode(t('profile_settings.profile_updated_success') ?? 'Profile updated successfully!') ?>,
profileUpdateError: <?= json_encode(t('profile_settings.profile_update_error') ?? 'Error updating profile. Please try again.') ?>,
imageUploadError: <?= json_encode(t('profile_settings.image_upload_error') ?? 'Error uploading image. Please try again.') ?>,
imageUploadSuccess: <?= json_encode(t('profile_settings.image_upload_success') ?? 'Profile image uploaded successfully!') ?>,
invalidImageFile: <?= json_encode(t('profile_settings.invalid_image_file') ?? 'Please select a valid image file.') ?>,
fileSizeError: <?= json_encode(t('profile_settings.file_size_error') ?? 'File size must be less than 5MB.') ?>
};
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(profileSettingsTranslations.invalidImageFile, 'error');
return;
}
// Validate file size (5MB max)
if (file.size > 5 * 1024 * 1024) {
showNotification(profileSettingsTranslations.fileSizeError, '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(profileSettingsTranslations.imageUploadSuccess, 'success');
} else {
showNotification(profileSettingsTranslations.imageUploadError + ': ' + (data.error || ''), 'error');
restoreOriginalState();
}
})
.catch(error => {
console.error('Error:', error);
showNotification(profileSettingsTranslations.imageUploadError, '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(profileSettingsTranslations.removeImageConfirm)) {
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> ' + profileSettingsTranslations.uploadPhoto;
}
showNotification(profileSettingsTranslations.imageRemovedSuccess, 'success');
} else {
showNotification(profileSettingsTranslations.imageRemoveError + ': ' + (data.error || ''), 'error');
}
})
.catch(error => {
console.error('Error:', error);
showNotification(profileSettingsTranslations.imageRemoveError, '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] = [];
}
// For checkboxes, include the value even if empty (they're either checked or not)
const trimmedValue = value.trim();
if (trimmedValue) {
data[arrayKey].push(trimmedValue);
}
} else {
// For text inputs, trim but allow empty strings for optional fields
data[key] = value.trim();
}
}
// DEBUG: Log what we're sending
console.log('Form data being sent:', data);
console.log('PayPal.Me username value:', data.paypal_me_username);
// 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(profileSettingsTranslations.artistNameRequired, 'error');
const saveBtn = document.querySelector('.save-btn');
saveBtn.innerHTML = '<i class="fas fa-save"></i> ' + profileSettingsTranslations.saveChanges;
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> ' + profileSettingsTranslations.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(profileSettingsTranslations.profileUpdatedSuccess, 'success');
// Reload page after a short delay to show updated data
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
const errorMsg = result.error || profileSettingsTranslations.profileUpdateError;
showNotification(errorMsg, 'error');
saveBtn.innerHTML = originalText;
saveBtn.disabled = false;
}
} catch (error) {
console.error('Profile update error:', error);
showNotification(profileSettingsTranslations.profileUpdateError, 'error');
const saveBtn = document.querySelector('.save-btn');
saveBtn.innerHTML = '<i class="fas fa-save"></i> ' + profileSettingsTranslations.saveChanges;
saveBtn.disabled = false;
}
});
</script>
<?php include 'includes/footer.php'; ?>