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:
1 parent
f66b2749f0
commit
006c865b87
5 files changed
+42
-2
No files matched your search
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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' });
|
||||
|
||||
Reference in new issue
Block a user