Add emoji toggle setting to parent dashboard Settings panel

Parent can turn the floating school emoji on/off from Settings > Student home screen. Setting persists in the DB and is read via a public /api/public-settings endpoint on the student home page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 4.6 committed 2026-08-04 17:00:42 -04:00
1 parent f66b2749f0
commit 006c865b87
5 files changed
+42 -2

No files matched your search

+9
View File
@@ -535,6 +535,15 @@
</label>
</div>
<div class="field-group" style="margin-top:1rem">
<label>Student home screen</label>
<label class="toggle-label" style="margin-top:.5rem">
<input type="checkbox" id="setting-show-emoji" role="switch">
<span class="toggle-track"><span class="toggle-thumb"></span></span>
Show floating emoji on the kid picker screen
</label>
</div>
<button type="submit" style="margin-top:1.25rem">Save settings</button>
</form>
+3 -1
View File
@@ -2488,6 +2488,7 @@ async function loadSettings() {
$('#setting-passing-pct').value = appSettings.passingPct;
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;
}
$('#app-settings-form').addEventListener('submit', async (e) => {
@@ -2495,7 +2496,8 @@ $('#app-settings-form').addEventListener('submit', async (e) => {
const school_name = $('#setting-school-name').value.trim();
const passing_pct = Number($('#setting-passing-pct').value);
const week_start_day = document.querySelector('input[name="week_start_day"]:checked')?.value || 'monday';
await api('/api/admin/app-settings', { method: 'POST', body: { school_name, passing_pct, week_start_day } });
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;
appSettings.passingPct = passing_pct;
if (appSettings.weekStartDay !== week_start_day) {
+4
View File
@@ -243,6 +243,10 @@ async function loadHome() {
: 'Good evening! 🌙';
document.querySelector('.subtitle').textContent = greeting;
const pubSettings = await fetch('/api/public-settings').then((r) => r.json()).catch(() => ({}));
document.querySelector('.page-confetti').style.display =
pubSettings.show_home_emoji === false ? 'none' : '';
const students = await api('/api/students');
$('#no-kids').hidden = students.length > 0;
$('#kid-cards').innerHTML = students
+19
View File
@@ -843,6 +843,25 @@ button.tiny { font-size: 0.75rem; padding: 0.15rem 0.5rem; }
.radio-label { display: block; margin: 0.3rem 0; cursor: pointer; }
.radio-label input { margin-right: 0.4rem; }
.toggle-label {
display: flex; align-items: center; gap: 0.65rem;
cursor: pointer; font-size: 0.95rem; user-select: none;
}
.toggle-label input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle-track {
flex-shrink: 0; width: 40px; height: 22px;
background: #d0ccc0; border-radius: 999px;
position: relative; transition: background 0.2s;
}
.toggle-thumb {
position: absolute; top: 3px; left: 3px;
width: 16px; height: 16px; border-radius: 50%;
background: #fff; box-shadow: 0 1px 4px rgba(0,0,0,0.2);
transition: transform 0.2s;
}
.toggle-label input:checked ~ .toggle-track { background: var(--accent); }
.toggle-label input:checked ~ .toggle-track .toggle-thumb { transform: translateX(18px); }
/* ---------- new features: locked items, due dates, overdue, history, modal ---------- */
.today-row.locked {
opacity: 0.55;
+7 -1
View File
@@ -673,18 +673,24 @@ app.get('/api/admin/app-settings', requirePin, (req, res) => {
school_name: getSetting('school_name') || '',
passing_pct: Number(getSetting('passing_pct') || 80),
week_start_day: getSetting('week_start_day') || 'monday',
show_home_emoji: getSetting('show_home_emoji') !== 'false',
});
});
app.post('/api/admin/app-settings', requirePin, (req, res) => {
const { school_name, passing_pct, week_start_day } = req.body;
const { school_name, passing_pct, week_start_day, show_home_emoji } = req.body;
const upsert = (k, v) => db.prepare(`INSERT INTO settings (key,value) VALUES (?,?) ON CONFLICT(key) DO UPDATE SET value=excluded.value`).run(k, String(v));
if (school_name !== undefined) upsert('school_name', String(school_name).trim());
if (passing_pct !== undefined) upsert('passing_pct', Math.max(0, Math.min(100, Number(passing_pct))));
if (week_start_day !== undefined && ['monday', 'sunday'].includes(week_start_day)) upsert('week_start_day', week_start_day);
if (show_home_emoji !== undefined) upsert('show_home_emoji', show_home_emoji ? 'true' : 'false');
res.json({ ok: true });
});
app.get('/api/public-settings', (req, res) => {
res.json({ show_home_emoji: getSetting('show_home_emoji') !== 'false' });
});
app.post('/api/students', requirePin, (req, res) => {
const name = String(req.body.name || '').trim();
if (!name) return res.status(400).json({ error: 'Name required' });