Add role-based access control and consistent header UI for website

- Add role-based access control: brokers cannot access player.html and players cannot access broker.html
- Update profile.html header to match player/broker dashboard style with dropdown menu
- Update wallet.html header to match player/broker dashboard style with dropdown menu
- Remove hardcoded player.html link from profile.html, use role-based dashboard link
- Fix authentication token key consistency (authToken instead of access_token)
parent b093ecb5
...@@ -11,6 +11,14 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -11,6 +11,14 @@ document.addEventListener('DOMContentLoaded', () => {
// Only load data if we have a valid token // Only load data if we have a valid token
if (authToken) { if (authToken) {
// Check role-based access - only brokers can access this page
if (currentUser && currentUser.role === 'player') {
console.log('Player user attempted to access broker area, redirecting to player dashboard');
showNotification('Players do not have access to the broker area.', 'error');
window.location.href = 'player.html';
return;
}
console.log('Loading broker data...'); console.log('Loading broker data...');
loadBrokerData(); loadBrokerData();
} else { } else {
......
...@@ -436,6 +436,14 @@ document.addEventListener('DOMContentLoaded', async () => { ...@@ -436,6 +436,14 @@ document.addEventListener('DOMContentLoaded', async () => {
// Only load data if we have a valid token // Only load data if we have a valid token
if (authToken) { if (authToken) {
// Check role-based access - only players can access this page
if (currentUser && currentUser.role === 'broker') {
console.log('Broker user attempted to access player area, redirecting to broker dashboard');
showNotification('Brokers do not have access to the player area.', 'error');
window.location.href = 'broker.html';
return;
}
// Load streaming config first to get the correct video URL // Load streaming config first to get the correct video URL
await loadStreamingConfig(); await loadStreamingConfig();
......
...@@ -7,16 +7,28 @@ ...@@ -7,16 +7,28 @@
<link rel="stylesheet" href="styles.css"> <link rel="stylesheet" href="styles.css">
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<header class="dashboard-header"> <header class="dashboard-header">
<div> <div>
<h1 class="dashboard-title">Profile Settings</h1> <h1 class="dashboard-title">Profile Settings</h1>
<p class="tagline">Manage your account settings</p> <p class="tagline">Manage your account settings</p>
</div> </div>
<div class="user-info"> <div class="user-info">
<span id="user-name">Welcome</span> <span id="user-balance" class="balance-display">Balance: $0.00</span>
<a href="player.html" class="btn btn-secondary" id="back-to-dashboard">Back to Dashboard</a> <div class="nav-user">
<button class="logout-btn" onclick="logout()">Logout</button> <div class="user-profile" onclick="toggleUserDropdown()">
<img id="user-avatar" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='50' fill='%234a5568'/%3E%3Ccircle cx='50' cy='35' r='20' fill='%23718096'/%3E%3Cellipse cx='50' cy='85' rx='35' ry='25' fill='%23718096'/%3E%3C/svg%3E" alt="Avatar" class="user-avatar">
<span id="user-name" class="user-welcome">User</span>
<span class="dropdown-arrow"></span>
</div>
<div id="user-dropdown" class="user-dropdown" style="display: none;">
<a href="#" class="dropdown-item" id="dashboard-link" onclick="goToDashboard(); return false;">📊 Dashboard</a>
<a href="wallet.html" class="dropdown-item">💰 Wallet</a>
<a href="profile.html" class="dropdown-item">⚙️ Profile Settings</a>
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item" onclick="logout(); return false;">🚪 Logout</a>
</div>
</div>
</div> </div>
</header> </header>
...@@ -242,7 +254,7 @@ ...@@ -242,7 +254,7 @@
// Check authentication // Check authentication
async function checkAuth() { async function checkAuth() {
const token = localStorage.getItem('access_token'); const token = localStorage.getItem('authToken');
if (!token) { if (!token) {
window.location.href = 'index.html'; window.location.href = 'index.html';
return false; return false;
...@@ -250,6 +262,34 @@ ...@@ -250,6 +262,34 @@
return true; return true;
} }
// Toggle user dropdown menu
function toggleUserDropdown() {
const dropdown = document.getElementById('user-dropdown');
if (dropdown) {
dropdown.style.display = dropdown.style.display === 'none' ? 'block' : 'none';
}
}
// Go to dashboard based on user role
function goToDashboard() {
if (currentUser && currentUser.role) {
if (currentUser.role === 'broker') {
window.location.href = 'broker.html';
} else {
window.location.href = 'player.html';
}
}
}
// Close dropdown when clicking outside
document.addEventListener('click', function(e) {
const dropdown = document.getElementById('user-dropdown');
const userProfile = document.querySelector('.user-profile');
if (dropdown && userProfile && !userProfile.contains(e.target)) {
dropdown.style.display = 'none';
}
});
// Load profile data // Load profile data
async function loadProfile() { async function loadProfile() {
try { try {
...@@ -429,13 +469,13 @@ ...@@ -429,13 +469,13 @@
} }
}; };
// Update welcome message // Update header welcome message
document.getElementById('user-name').textContent = `Welcome, ${displayName}`; document.getElementById('user-name').textContent = displayName;
// Update back button based on role // Update header avatar
const backBtn = document.getElementById('back-to-dashboard'); const headerAvatar = document.getElementById('user-avatar');
if (currentUser.role === 'broker') { if (headerAvatar) {
backBtn.href = 'broker.html'; headerAvatar.src = getAvatarUrl(currentUser, 32);
} }
} }
...@@ -469,6 +509,12 @@ ...@@ -469,6 +509,12 @@
document.getElementById('total-deposited').textContent = formatCurrency(walletData.total_deposited || 0); document.getElementById('total-deposited').textContent = formatCurrency(walletData.total_deposited || 0);
document.getElementById('total-withdrawn').textContent = formatCurrency(walletData.total_withdrawn || 0); document.getElementById('total-withdrawn').textContent = formatCurrency(walletData.total_withdrawn || 0);
document.getElementById('withdraw-available').textContent = formatCurrency(walletData.available_balance || walletData.balance); document.getElementById('withdraw-available').textContent = formatCurrency(walletData.available_balance || walletData.balance);
// Update header balance display
const headerBalance = document.getElementById('user-balance');
if (headerBalance) {
headerBalance.textContent = `Balance: ${formatCurrency(walletData.balance)}`;
}
} }
// Change password // Change password
...@@ -812,8 +858,10 @@ ...@@ -812,8 +858,10 @@
// Logout function // Logout function
function logout() { function logout() {
localStorage.removeItem('access_token'); localStorage.removeItem('authToken');
localStorage.removeItem('refresh_token'); localStorage.removeItem('currentUser');
localStorage.removeItem('refreshToken');
localStorage.removeItem('tokenExpiresAt');
window.location.href = 'index.html'; window.location.href = 'index.html';
} }
</script> </script>
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment