Add school name and logo to home screen and admin header
- School name now appears on the student home screen and updates the page title - Logo can be uploaded in Settings (PNG/JPG/GIF/WebP/SVG, max 2 MB); stored in the data volume so it persists across container restarts - When a logo is uploaded the text school name is hidden in favour of the logo - Admin header shows the school name instead of hardcoded "Homeschool", updates live when saved - New server endpoints: GET /api/logo, POST /api/admin/upload-logo, DELETE /api/admin/logo - /api/public-settings now includes school_name and has_logo Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
1eedfc7715
commit
6b7baf7297
6 files changed
+135
-5
No files matched your search
@@ -58,12 +58,17 @@ $('#pin-form').addEventListener('submit', async (e) => {
|
||||
unlock();
|
||||
});
|
||||
|
||||
function updateAdminHeader() {
|
||||
$('#admin-school-name').textContent = `🎓 ${appSettings.schoolName || 'Homeschool'}`;
|
||||
}
|
||||
|
||||
async function loadAppSettings() {
|
||||
try {
|
||||
const s = await api('/api/admin/app-settings');
|
||||
appSettings.schoolName = s.school_name || '';
|
||||
appSettings.passingPct = Number(s.passing_pct) || 80;
|
||||
appSettings.weekStartDay = s.week_start_day || 'monday';
|
||||
updateAdminHeader();
|
||||
} catch {}
|
||||
}
|
||||
|
||||
@@ -2551,8 +2556,49 @@ async function loadSettings() {
|
||||
const radio = document.querySelector(`input[name="week_start_day"][value="${appSettings.weekStartDay}"]`);
|
||||
if (radio) radio.checked = true;
|
||||
$('#setting-show-emoji').checked = s.show_home_emoji !== false;
|
||||
|
||||
const pub = await fetch('/api/public-settings').then((r) => r.json()).catch(() => ({}));
|
||||
setLogoPreview(pub.has_logo);
|
||||
}
|
||||
|
||||
function setLogoPreview(hasLogo) {
|
||||
const preview = $('#logo-preview');
|
||||
const noneMsg = $('#logo-none-msg');
|
||||
const removeBtn = $('#logo-remove-btn');
|
||||
if (hasLogo) {
|
||||
preview.src = `/api/logo?v=${Date.now()}`;
|
||||
preview.hidden = false;
|
||||
noneMsg.hidden = true;
|
||||
removeBtn.hidden = false;
|
||||
} else {
|
||||
preview.hidden = true;
|
||||
noneMsg.hidden = false;
|
||||
removeBtn.hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
$('#logo-file-input').addEventListener('change', async (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
if (file.size > 2 * 1024 * 1024) { msg('Logo must be under 2 MB.'); e.target.value = ''; return; }
|
||||
const b64 = await new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => resolve(reader.result.split(',')[1]);
|
||||
reader.onerror = reject;
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
await api('/api/admin/upload-logo', { method: 'POST', body: { base64: b64, mime: file.type } });
|
||||
e.target.value = '';
|
||||
setLogoPreview(true);
|
||||
msg('Logo saved.');
|
||||
});
|
||||
|
||||
$('#logo-remove-btn').addEventListener('click', async () => {
|
||||
await api('/api/admin/logo', { method: 'DELETE' });
|
||||
setLogoPreview(false);
|
||||
msg('Logo removed.');
|
||||
});
|
||||
|
||||
$('#app-settings-form').addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const school_name = $('#setting-school-name').value.trim();
|
||||
@@ -2561,6 +2607,7 @@ $('#app-settings-form').addEventListener('submit', async (e) => {
|
||||
const show_home_emoji = $('#setting-show-emoji').checked;
|
||||
await api('/api/admin/app-settings', { method: 'POST', body: { school_name, passing_pct, week_start_day, show_home_emoji } });
|
||||
appSettings.schoolName = school_name;
|
||||
updateAdminHeader();
|
||||
appSettings.passingPct = passing_pct;
|
||||
if (appSettings.weekStartDay !== week_start_day) {
|
||||
appSettings.weekStartDay = week_start_day;
|
||||
|
||||
Reference in new issue
Block a user