250 lines
11 KiB
Plaintext
250 lines
11 KiB
Plaintext
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<title data-text="title">Asteroid Radio - User Profile</title>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<link rel="stylesheet" type="text/css" href="/asteroid/static/asteroid.css">
|
||
<script lquery='(text (asteroid::get-auth-state-js-var))'></script>
|
||
<script src="/asteroid/static/js/profile.js"></script>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<h1>👤 USER PROFILE</h1>
|
||
<c:h>(asteroid::load-template "partial/navbar")</c:h>
|
||
|
||
<!-- User Profile Header -->
|
||
<div class="admin-section">
|
||
<h2>🎧 User Profile</h2>
|
||
<div class="profile-header">
|
||
<div class="avatar-section">
|
||
<div class="avatar-container" id="avatar-container">
|
||
<img id="user-avatar" src="/asteroid/static/icons/default-avatar.svg" alt="User Avatar" class="avatar-image">
|
||
<div class="avatar-overlay" onclick="document.getElementById('avatar-input').click()">
|
||
<span>Change</span>
|
||
</div>
|
||
</div>
|
||
<input type="file" id="avatar-input" accept="image/*" style="display: none" onchange="uploadAvatar(this)">
|
||
</div>
|
||
<div class="profile-info">
|
||
<div class="info-group">
|
||
<span class="info-label">Username:</span>
|
||
<span class="info-value" data-text="username">user</span>
|
||
</div>
|
||
<div class="info-group">
|
||
<span class="info-label">Role:</span>
|
||
<span class="info-value" data-text="user-role">listener</span>
|
||
</div>
|
||
<div class="info-group">
|
||
<span class="info-label">Member Since:</span>
|
||
<span class="info-value" data-text="join-date">2024-01-01</span>
|
||
</div>
|
||
<div class="info-group">
|
||
<span class="info-label">Last Active:</span>
|
||
<span class="info-value" data-text="last-active">Today</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Listening Statistics -->
|
||
<div class="admin-section">
|
||
<h2>📊 Listening Statistics</h2>
|
||
<div class="admin-grid">
|
||
<div class="status-card">
|
||
<h3>Total Listen Time</h3>
|
||
<p class="stat-number" data-text="total-listen-time">0h 0m</p>
|
||
</div>
|
||
<div class="status-card">
|
||
<h3>Tracks Played</h3>
|
||
<p class="stat-number" data-text="tracks-played">0</p>
|
||
</div>
|
||
<div class="status-card">
|
||
<h3>Sessions</h3>
|
||
<p class="stat-number" data-text="session-count">0</p>
|
||
</div>
|
||
<div class="status-card">
|
||
<h3>Favorite Genre</h3>
|
||
<p class="stat-text" data-text="favorite-genre">Unknown</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- My Track Requests -->
|
||
<div class="admin-section">
|
||
<h2>🎵 My Track Requests</h2>
|
||
<div id="my-requests-list" class="requests-list">
|
||
<p class="loading-message">Loading your requests...</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- My Playlists -->
|
||
<div class="admin-section">
|
||
<h2>📝 My Playlists</h2>
|
||
<p class="section-description">Create custom playlists from the music library and submit them for station airplay!</p>
|
||
<div class="playlist-actions">
|
||
<button class="btn btn-primary" onclick="showCreatePlaylistModal()">➕ Create New Playlist</button>
|
||
<button class="btn btn-secondary" onclick="showLibraryBrowser()">🎵 Browse Library</button>
|
||
</div>
|
||
<div id="my-playlists-list" class="playlists-list">
|
||
<p class="loading-message">Loading your playlists...</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Favorite Tracks -->
|
||
<div class="admin-section">
|
||
<h2>❤️ Favorite Tracks</h2>
|
||
<div class="favorites-list" id="favorites-list">
|
||
<p class="loading-message">Loading favorites...</p>
|
||
</div>
|
||
<div class="profile-actions">
|
||
<button class="btn btn-secondary" onclick="loadMoreFavorites()">Load More</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Top Artists -->
|
||
<div class="admin-section">
|
||
<h2>🎤 Top Artists</h2>
|
||
<div class="artist-stats">
|
||
<div class="artist-item">
|
||
<span class="artist-name" data-text="top-artist-1">Unknown Artist</span>
|
||
<span class="artist-plays" data-text="top-artist-1-plays">0 plays</span>
|
||
</div>
|
||
<div class="artist-item">
|
||
<span class="artist-name" data-text="top-artist-2"></span>
|
||
<span class="artist-plays" data-text="top-artist-2-plays"></span>
|
||
</div>
|
||
<div class="artist-item">
|
||
<span class="artist-name" data-text="top-artist-3"></span>
|
||
<span class="artist-plays" data-text="top-artist-3-plays"></span>
|
||
</div>
|
||
<div class="artist-item">
|
||
<span class="artist-name" data-text="top-artist-4"></span>
|
||
<span class="artist-plays" data-text="top-artist-4-plays"></span>
|
||
</div>
|
||
<div class="artist-item">
|
||
<span class="artist-name" data-text="top-artist-5"></span>
|
||
<span class="artist-plays" data-text="top-artist-5-plays"></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Listening Activity Chart -->
|
||
<div class="admin-section">
|
||
<h2>📈 Listening Activity</h2>
|
||
<div class="activity-chart">
|
||
<p>Tracks played over the last 30 days</p>
|
||
<div class="chart-container" id="activity-chart">
|
||
<p class="loading-message">Loading activity data...</p>
|
||
</div>
|
||
<p class="chart-note" id="activity-total">Total: 0 tracks</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Profile Actions -->
|
||
<div class="admin-section">
|
||
<h2>⚙️ Profile Settings</h2>
|
||
|
||
<!-- Change Password Form -->
|
||
<div class="form-section">
|
||
<h3>🔒 Change Password</h3>
|
||
<form id="change-password-form" onsubmit="return changePassword(event)">
|
||
<div class="form-group">
|
||
<label for="current-password">Current Password:</label>
|
||
<input type="password" id="current-password" name="current-password" required minlength="8">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="new-password">New Password:</label>
|
||
<input type="password" id="new-password" name="new-password" required minlength="8">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="confirm-password">Confirm New Password:</label>
|
||
<input type="password" id="confirm-password" name="confirm-password" required minlength="8">
|
||
</div>
|
||
<div id="password-message" class="message"></div>
|
||
<button type="submit" class="btn btn-primary">Change Password</button>
|
||
</form>
|
||
</div>
|
||
|
||
<div class="profile-actions">
|
||
<button class="btn btn-primary" onclick="editProfile()">✏️ Edit Profile</button>
|
||
<button class="btn btn-secondary" onclick="exportListeningData()">📊 Export Data</button>
|
||
<button class="btn btn-secondary" onclick="clearListeningHistory()">🗑️ Clear History</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Create Playlist Modal -->
|
||
<div id="create-playlist-modal" class="modal" style="display: none;">
|
||
<div class="modal-content">
|
||
<span class="modal-close" onclick="hideCreatePlaylistModal()">×</span>
|
||
<h2>Create New Playlist</h2>
|
||
<form id="create-playlist-form" onsubmit="return createPlaylist(event)">
|
||
<div class="form-group">
|
||
<label for="playlist-name">Playlist Name:</label>
|
||
<input type="text" id="playlist-name" name="name" required maxlength="100" placeholder="My Awesome Playlist">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="playlist-description">Description (optional):</label>
|
||
<textarea id="playlist-description" name="description" maxlength="500" rows="3" placeholder="Describe your playlist..."></textarea>
|
||
</div>
|
||
<div id="create-playlist-message" class="message"></div>
|
||
<button type="submit" class="btn btn-primary">Create Playlist</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Library Browser Modal -->
|
||
<div id="library-browser-modal" class="modal" style="display: none; z-index: 1100;">
|
||
<div class="modal-content modal-large">
|
||
<span class="modal-close" onclick="hideLibraryBrowser()">×</span>
|
||
<h2>🎵 Music Library</h2>
|
||
<div class="library-controls">
|
||
<input type="text" id="library-search" placeholder="Search tracks..." onkeyup="searchLibrary()">
|
||
<select id="library-artist-filter" onchange="filterByArtist()">
|
||
<option value="">All Artists</option>
|
||
</select>
|
||
<select id="add-to-playlist-select">
|
||
<option value="">Select playlist to add to...</option>
|
||
</select>
|
||
</div>
|
||
<div id="library-tracks" class="library-tracks-list">
|
||
<p class="loading-message">Loading library...</p>
|
||
</div>
|
||
<div class="library-pagination">
|
||
<button class="btn btn-secondary" onclick="prevLibraryPage()" id="lib-prev-btn" disabled>← Previous</button>
|
||
<span id="library-page-info">Page 1</span>
|
||
<button class="btn btn-secondary" onclick="nextLibraryPage()" id="lib-next-btn">Next →</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Edit Playlist Modal -->
|
||
<div id="edit-playlist-modal" class="modal" style="display: none;">
|
||
<div class="modal-content modal-large">
|
||
<span class="modal-close" onclick="hideEditPlaylistModal()">×</span>
|
||
<h2 id="edit-playlist-title">Edit Playlist</h2>
|
||
<div class="playlist-edit-header">
|
||
<input type="text" id="edit-playlist-name" placeholder="Playlist name">
|
||
<textarea id="edit-playlist-description" placeholder="Description..." rows="2"></textarea>
|
||
<button class="btn btn-secondary" onclick="savePlaylistMetadata()">Save Details</button>
|
||
</div>
|
||
<div class="playlist-tracks-container">
|
||
<h3>Tracks in Playlist</h3>
|
||
<div id="playlist-tracks-list" class="playlist-tracks-sortable">
|
||
<p class="empty-message">No tracks yet. Browse the library to add tracks!</p>
|
||
</div>
|
||
</div>
|
||
<div class="playlist-edit-actions">
|
||
<button class="btn btn-secondary" onclick="showLibraryBrowserForPlaylist()">➕ Add Tracks</button>
|
||
<button class="btn btn-primary" onclick="submitPlaylistForReview()" id="submit-playlist-btn">📤 Submit for Review</button>
|
||
<button class="btn btn-danger" onclick="deleteCurrentPlaylist()">🗑️ Delete Playlist</button>
|
||
</div>
|
||
<input type="hidden" id="current-edit-playlist-id" value="">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Initialization handled by profile.js -->
|
||
</body>
|
||
</html>
|