update ui and other frontend updates

This commit is contained in:
JCEEE
2026-07-29 09:41:52 +01:00
parent 04b83925e0
commit 57ef30d3a7
79 changed files with 7323 additions and 429 deletions
@@ -0,0 +1,122 @@
import { fail, redirect } from '@sveltejs/kit';
import { hono } from '$lib/server/hono';
import { memberApi } from '$lib/client/api';
import { SERVER_IP, PROXY_PORT } from '../../../../../config.ts';
const HONO_URL = `http://${SERVER_IP}:${PROXY_PORT}`;
export async function load(event) {
const session = event.locals.session;
// Parent (session auth) → admin overview
if (session) {
const famId = session.famId;
const famSlug = event.params.fam;
const username = event.params.username;
if (session.memberName && session.memberName !== username) {
throw redirect(303, `/${famSlug}/${session.memberName}`);
}
const [members, templates, assigned, summary, fam, rewards, bonusConfigs, completions] = await Promise.all([
hono.admin.list(event, 'members', famId),
hono.admin.list(event, 'chore-templates', famId),
hono.admin.list(event, 'assigned-chores', famId),
hono.admin.weeklySummary(event, famId),
hono.admin.fam(event, famId),
hono.admin.rewards(event, famId),
hono.admin.bonusConfigs(event, famId),
hono.admin.completions(event, famId),
]);
return { role: 'parent', members, templates, assigned, summary, fam, famSlug, rewards, bonusConfigs, completions };
}
// Child (device token) → kanban
const deviceToken = event.cookies.get('device_token') || event.url.searchParams.get('token') || '';
const famSlug = event.params.fam;
const username = event.params.username;
if (!deviceToken) {
return { role: 'child', token: '', memberId: '', verified: false, famId: '', templates: [], assigned: [], completions: [], rewards: [], bonusConfigs: [], tallies: {} };
}
try {
const res = await fetch(`${HONO_URL}/api/members/verify-token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ deviceToken, famSlug }),
});
const data = await res.json();
if (!res.ok || data.name !== username) {
return { role: 'child', token: deviceToken, memberId: '', verified: false, famId: '', memberName: '', memberColor: '', templates: [], assigned: [], completions: [], rewards: [], bonusConfigs: [], tallies: {} };
}
let chores: any = {};
try {
chores = await memberApi.myChores(deviceToken, data.famId);
} catch {}
return {
role: 'child',
token: deviceToken,
memberId: data.memberId,
famId: data.famId,
verified: true,
memberName: data.name,
memberColor: data.color,
templates: chores.templates || [],
assigned: chores.assigned || [],
completions: chores.completions || [],
rewards: chores.rewards || [],
bonusConfigs: chores.bonusConfigs || [],
tallies: chores.tallies || {},
};
} catch {
return { role: 'child', token: deviceToken, memberId: '', verified: false, famId: '', templates: [], assigned: [], completions: [], rewards: [], bonusConfigs: [], tallies: {} };
}
}
export const actions = {
claim: async (event) => {
if (!event.locals.session) throw redirect(303, '/login');
const famId = event.locals.session.famId;
const fd = await event.request.formData();
const rewardId = fd.get('id') as string;
const message = fd.get('message') as string;
try {
const record = await hono.admin.claimReward(event, famId, rewardId);
if (message) {
await hono.admin.sendMessage(event, famId, record.memberId, message);
}
return { record };
} catch (e) {
return { error: e instanceof Error ? e.message : 'Failed to claim reward' };
}
},
revoke: async (event) => {
if (!event.locals.session) throw redirect(303, '/login');
const famId = event.locals.session.famId;
const fd = await event.request.formData();
const completionId = fd.get('id') as string;
try {
await hono.admin.revokeCompletion(event, famId, completionId);
return { revoked: true, id: completionId };
} catch (e) {
return { error: e instanceof Error ? e.message : 'Failed to revoke' };
}
},
trigger: async (event) => {
if (!event.locals.session) throw redirect(303, '/login');
const famId = event.locals.session.famId;
const fd = await event.request.formData();
const configId = fd.get('configId') as string;
const memberId = fd.get('memberId') as string;
if (!configId) return { error: 'Config ID required' };
try {
const result = await hono.admin.triggerBonusConfig(event, famId, configId, memberId || undefined);
return { records: result.records || [] };
} catch (e) {
return { error: e instanceof Error ? e.message : 'Failed to trigger' };
}
},
};