White-label multi-domain tuki (Noxus Intra)
- CSS-muuttujat: kaikki kovakoodatut #0f3460/#16213e korvattu var(--primary-color)/var(--primary-dark) - Uudet API-endpointit: branding (julkinen, domain-pohjainen), company_logo, company_logo_upload - Domain-pohjainen brändäys: HTTP_HOST → yrityksen domains-arrayn matchaus - Login: domain asettaa oletusyrityksen sessioon - check_auth: palauttaa branding-objektin (primary_color, subtitle, logo_url) - company_create/update: käsittelee domains, primary_color, subtitle, logo_file - Dynaaminen login-sivu, header ja footer (logo, nimi, alaotsikko, värit) - JS: loadBranding(), applyBranding(), yritysvaihdon brändäyspäivitys - Admin-paneeli: brändäysasetukset (logo-upload, väri, alaotsikko, domainit) - Git-repo siirretty intra.noxus.fi:hin Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
124
script.js
124
script.js
@@ -136,6 +136,7 @@ async function checkAuth() {
|
||||
availableCompanies = data.companies || [];
|
||||
currentCompany = availableCompanies.find(c => c.id === data.company_id) || availableCompanies[0] || null;
|
||||
currentUserSignatures = data.signatures || {};
|
||||
if (data.branding) applyBranding(data.branding);
|
||||
showDashboard();
|
||||
}
|
||||
} catch (e) { /* not logged in */ }
|
||||
@@ -171,6 +172,7 @@ document.getElementById('btn-logout').addEventListener('click', async () => {
|
||||
document.getElementById('login-captcha').value = '';
|
||||
showLoginView();
|
||||
loadCaptcha();
|
||||
loadBranding(); // Domain-pohjainen brändäys uudelleen
|
||||
});
|
||||
|
||||
async function showDashboard() {
|
||||
@@ -206,6 +208,11 @@ async function switchCompany(companyId) {
|
||||
try {
|
||||
await apiCall('company_switch', 'POST', { company_id: companyId });
|
||||
currentCompany = availableCompanies.find(c => c.id === companyId) || null;
|
||||
// Päivitä brändäys vaihdetun yrityksen mukaan
|
||||
try {
|
||||
const auth = await apiCall('check_auth');
|
||||
if (auth.branding) applyBranding(auth.branding);
|
||||
} catch (e2) {}
|
||||
// Lataa uudelleen aktiivinen tab
|
||||
const hash = window.location.hash.replace('#', '') || 'customers';
|
||||
switchToTab(hash);
|
||||
@@ -1837,6 +1844,20 @@ async function showCompanyDetail(id) {
|
||||
const comp = companiesTabData.find(c => c.id === id);
|
||||
document.getElementById('company-detail-title').textContent = (comp ? comp.nimi : id) + ' — Asetukset';
|
||||
document.getElementById('company-edit-nimi').value = comp ? comp.nimi : '';
|
||||
// Brändäyskentät
|
||||
document.getElementById('company-edit-subtitle').value = comp?.subtitle || '';
|
||||
const color = comp?.primary_color || '#0f3460';
|
||||
document.getElementById('company-edit-color').value = color;
|
||||
document.getElementById('company-edit-color-text').value = color;
|
||||
document.getElementById('company-edit-domains').value = (comp?.domains || []).join('\n');
|
||||
// Logo-esikatselu
|
||||
const logoPreview = document.getElementById('company-logo-preview');
|
||||
if (comp?.logo_file) {
|
||||
logoPreview.src = 'api.php?action=company_logo&company_id=' + encodeURIComponent(id) + '&t=' + Date.now();
|
||||
logoPreview.style.display = '';
|
||||
} else {
|
||||
logoPreview.style.display = 'none';
|
||||
}
|
||||
|
||||
// Vaihda aktiivinen yritys jotta API-kutsut kohdistuvat oikein
|
||||
await apiCall('company_switch', 'POST', { company_id: id });
|
||||
@@ -1853,18 +1874,60 @@ document.getElementById('btn-company-back').addEventListener('click', () => {
|
||||
renderCompaniesTable();
|
||||
});
|
||||
|
||||
document.getElementById('btn-save-company-name').addEventListener('click', async () => {
|
||||
// Synkronoi color picker <-> text input
|
||||
document.getElementById('company-edit-color').addEventListener('input', function() {
|
||||
document.getElementById('company-edit-color-text').value = this.value;
|
||||
});
|
||||
document.getElementById('company-edit-color-text').addEventListener('input', function() {
|
||||
if (/^#[0-9a-fA-F]{6}$/.test(this.value)) {
|
||||
document.getElementById('company-edit-color').value = this.value;
|
||||
}
|
||||
});
|
||||
|
||||
// Logo-upload
|
||||
document.getElementById('company-logo-upload').addEventListener('change', async function() {
|
||||
if (!this.files[0] || !currentCompanyDetail) return;
|
||||
const formData = new FormData();
|
||||
formData.append('logo', this.files[0]);
|
||||
formData.append('company_id', currentCompanyDetail);
|
||||
try {
|
||||
const res = await fetch('api.php?action=company_logo_upload', { method: 'POST', body: formData, credentials: 'include' });
|
||||
const data = await res.json();
|
||||
if (!res.ok) throw new Error(data.error || 'Virhe');
|
||||
// Päivitä preview
|
||||
const preview = document.getElementById('company-logo-preview');
|
||||
preview.src = data.logo_url + '&t=' + Date.now();
|
||||
preview.style.display = '';
|
||||
// Päivitä paikallinen data
|
||||
const comp = companiesTabData.find(c => c.id === currentCompanyDetail);
|
||||
if (comp) comp.logo_file = data.logo_file;
|
||||
} catch (e) { alert(e.message); }
|
||||
this.value = ''; // Reset file input
|
||||
});
|
||||
|
||||
document.getElementById('btn-save-company-settings').addEventListener('click', async () => {
|
||||
const nimi = document.getElementById('company-edit-nimi').value.trim();
|
||||
if (!nimi) return;
|
||||
const subtitle = document.getElementById('company-edit-subtitle').value.trim();
|
||||
const primary_color = document.getElementById('company-edit-color').value;
|
||||
const domainsText = document.getElementById('company-edit-domains').value;
|
||||
const domains = domainsText.split('\n').map(d => d.trim()).filter(d => d);
|
||||
try {
|
||||
await apiCall('company_update', 'POST', { id: currentCompanyDetail, nimi });
|
||||
alert('Nimi tallennettu!');
|
||||
await apiCall('company_update', 'POST', { id: currentCompanyDetail, nimi, subtitle, primary_color, domains });
|
||||
alert('Asetukset tallennettu!');
|
||||
// Päivitä paikalliset tiedot
|
||||
const comp = companiesTabData.find(c => c.id === currentCompanyDetail);
|
||||
if (comp) comp.nimi = nimi;
|
||||
if (comp) { comp.nimi = nimi; comp.subtitle = subtitle; comp.primary_color = primary_color; comp.domains = domains; }
|
||||
const avail = availableCompanies.find(c => c.id === currentCompanyDetail);
|
||||
if (avail) avail.nimi = nimi;
|
||||
populateCompanySelector();
|
||||
// Jos tämä on aktiivinen yritys → päivitä brändäys heti
|
||||
if (currentCompany && currentCompany.id === currentCompanyDetail) {
|
||||
applyBranding({
|
||||
nimi, subtitle, primary_color,
|
||||
logo_url: comp?.logo_file ? 'api.php?action=company_logo&company_id=' + encodeURIComponent(currentCompanyDetail) + '&t=' + Date.now() : ''
|
||||
});
|
||||
}
|
||||
} catch (e) { alert(e.message); }
|
||||
});
|
||||
|
||||
@@ -1985,6 +2048,59 @@ async function toggleCompanyUser(userId, companyId, add) {
|
||||
} catch (e) { alert(e.message); }
|
||||
}
|
||||
|
||||
// ==================== BRANDING ====================
|
||||
|
||||
function applyBranding(branding) {
|
||||
const color = branding.primary_color || '#0f3460';
|
||||
const nimi = branding.nimi || 'Noxus Intra';
|
||||
const subtitle = branding.subtitle || '';
|
||||
const logoUrl = branding.logo_url || '';
|
||||
|
||||
// CSS-muuttuja
|
||||
document.documentElement.style.setProperty('--primary-color', color);
|
||||
// Laske tumma variantti
|
||||
document.documentElement.style.setProperty('--primary-dark', color);
|
||||
|
||||
// Login-sivu
|
||||
const loginLogo = document.getElementById('login-logo');
|
||||
const loginTitle = document.getElementById('login-title');
|
||||
const loginSubtitle = document.getElementById('login-subtitle');
|
||||
if (loginLogo) {
|
||||
if (logoUrl) { loginLogo.src = logoUrl; loginLogo.style.display = ''; }
|
||||
else { loginLogo.style.display = 'none'; }
|
||||
}
|
||||
if (loginTitle) loginTitle.textContent = nimi;
|
||||
if (loginSubtitle) loginSubtitle.textContent = subtitle || 'Kirjaudu sisään';
|
||||
// Muut login-boxien otsikot
|
||||
document.querySelectorAll('.login-brand-title').forEach(el => el.textContent = nimi);
|
||||
|
||||
// Header
|
||||
const headerLogo = document.getElementById('header-logo');
|
||||
const headerIcon = document.getElementById('header-brand-icon');
|
||||
const headerTitle = document.getElementById('header-title');
|
||||
const headerSubtitle = document.getElementById('header-subtitle');
|
||||
if (headerLogo) {
|
||||
if (logoUrl) { headerLogo.src = logoUrl; headerLogo.style.display = ''; if (headerIcon) headerIcon.style.display = 'none'; }
|
||||
else { headerLogo.style.display = 'none'; if (headerIcon) headerIcon.style.display = ''; }
|
||||
}
|
||||
if (headerTitle) headerTitle.textContent = nimi;
|
||||
if (headerSubtitle) headerSubtitle.textContent = subtitle || 'Hallintapaneeli';
|
||||
|
||||
// Sivun title
|
||||
document.title = nimi;
|
||||
}
|
||||
|
||||
async function loadBranding() {
|
||||
try {
|
||||
const data = await apiCall('branding');
|
||||
applyBranding(data);
|
||||
} catch (e) {
|
||||
// Oletusbrändäys
|
||||
applyBranding({ nimi: 'Noxus Intra', primary_color: '#0f3460', subtitle: 'Hallintapaneeli', logo_url: '' });
|
||||
}
|
||||
}
|
||||
|
||||
// Init
|
||||
loadBranding();
|
||||
loadCaptcha();
|
||||
checkAuth();
|
||||
|
||||
Reference in New Issue
Block a user