147 lines
4.6 KiB
JavaScript
147 lines
4.6 KiB
JavaScript
|
|
// Academy Auth Integration
|
||
|
|
// Kopplar academy-progress till quiXzoom inloggningssystem
|
||
|
|
|
||
|
|
class AcademyAuth {
|
||
|
|
constructor() {
|
||
|
|
this.apiUrl = 'https://api.quixzoom.com';
|
||
|
|
this.token = this.getToken();
|
||
|
|
this.user = this.getUser();
|
||
|
|
}
|
||
|
|
|
||
|
|
getToken() {
|
||
|
|
// Kolla flera möjliga token-lagringar
|
||
|
|
return localStorage.getItem('qz_token') ||
|
||
|
|
localStorage.getItem('auth_token') ||
|
||
|
|
sessionStorage.getItem('qz_token') ||
|
||
|
|
this.getCookie('qz_session');
|
||
|
|
}
|
||
|
|
|
||
|
|
getUser() {
|
||
|
|
try {
|
||
|
|
return JSON.parse(localStorage.getItem('qz_user') || '{}');
|
||
|
|
} catch {
|
||
|
|
return {};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
getCookie(name) {
|
||
|
|
const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
|
||
|
|
return match ? match[2] : null;
|
||
|
|
}
|
||
|
|
|
||
|
|
isLoggedIn() {
|
||
|
|
return !!this.token;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Hämta progress från backend
|
||
|
|
async fetchProgress() {
|
||
|
|
if (!this.isLoggedIn()) return null;
|
||
|
|
|
||
|
|
try {
|
||
|
|
const response = await fetch(`${this.apiUrl}/academy/progress`, {
|
||
|
|
headers: {
|
||
|
|
'Authorization': `Bearer ${this.token}`,
|
||
|
|
'Content-Type': 'application/json'
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
if (response.ok) {
|
||
|
|
const data = await response.json();
|
||
|
|
// Spara till localStorage som backup
|
||
|
|
localStorage.setItem('academyProgress', JSON.stringify(data.completedLessons || []));
|
||
|
|
return data;
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.warn('Kunde inte hämta progress från backend:', error);
|
||
|
|
}
|
||
|
|
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Spara progress till backend
|
||
|
|
async saveProgress(lessonId) {
|
||
|
|
if (!this.isLoggedIn()) {
|
||
|
|
// Spara lokalt tills användaren loggar in
|
||
|
|
this.saveLocalProgress(lessonId);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const response = await fetch(`${this.apiUrl}/academy/progress`, {
|
||
|
|
method: 'POST',
|
||
|
|
headers: {
|
||
|
|
'Authorization': `Bearer ${this.token}`,
|
||
|
|
'Content-Type': 'application/json'
|
||
|
|
},
|
||
|
|
body: JSON.stringify({ lessonId, completedAt: new Date().toISOString() })
|
||
|
|
});
|
||
|
|
|
||
|
|
if (response.ok) {
|
||
|
|
// Uppdatera även localStorage
|
||
|
|
this.saveLocalProgress(lessonId);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.warn('Kunde inte spara progress till backend:', error);
|
||
|
|
// Fallback till localStorage
|
||
|
|
this.saveLocalProgress(lessonId);
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
saveLocalProgress(lessonId) {
|
||
|
|
const progress = JSON.parse(localStorage.getItem('academyProgress') || '[]');
|
||
|
|
if (!progress.includes(lessonId)) {
|
||
|
|
progress.push(lessonId);
|
||
|
|
localStorage.setItem('academyProgress', JSON.stringify(progress));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Visa inloggnings-prompt
|
||
|
|
showLoginPrompt() {
|
||
|
|
const prompt = document.createElement('div');
|
||
|
|
prompt.id = 'academy-login-prompt';
|
||
|
|
prompt.innerHTML = `
|
||
|
|
<div style="position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.5);z-index:10000;display:flex;align-items:center;justify-content:center;padding:20px">
|
||
|
|
<div style="background:white;border-radius:20px;padding:40px;max-width:400px;width:100%;text-align:center;box-shadow:0 20px 60px rgba(0,0,0,0.3)">
|
||
|
|
<div style="font-size:48px;margin-bottom:16px">🔐</div>
|
||
|
|
<h2 style="font-size:24px;font-weight:800;margin-bottom:12px">Logga in för att spara din progress</h2>
|
||
|
|
<p style="color:#6E6E73;margin-bottom:24px">Dina lektioner och certifiering sparas till ditt quiXzoom-konto så du kan fortsätta på vilken enhet som helst.</p>
|
||
|
|
<div style="display:flex;gap:12px;flex-direction:column">
|
||
|
|
<a href="/login?redirect=/academy/" style="background:#0066FF;color:white;padding:16px;border-radius:12px;text-decoration:none;font-weight:700;font-size:16px">Logga in</a>
|
||
|
|
<button onclick="document.getElementById('academy-login-prompt').remove()" style="background:#F5F5F7;color:#0A0A0A;padding:16px;border-radius:12px;border:none;font-weight:600;font-size:16px;cursor:pointer">Fortsätt utan inloggning</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
`;
|
||
|
|
document.body.appendChild(prompt);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Hämta certifiering
|
||
|
|
async getCertificate() {
|
||
|
|
if (!this.isLoggedIn()) return null;
|
||
|
|
|
||
|
|
try {
|
||
|
|
const response = await fetch(`${this.apiUrl}/academy/certificate`, {
|
||
|
|
headers: {
|
||
|
|
'Authorization': `Bearer ${this.token}`
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
if (response.ok) {
|
||
|
|
return await response.json();
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.warn('Kunde inte hämta certifikat:', error);
|
||
|
|
}
|
||
|
|
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Initiera
|
||
|
|
const academyAuth = new AcademyAuth();
|
||
|
|
|
||
|
|
// Exportera för global användning
|
||
|
|
window.academyAuth = academyAuth;
|