added todos | payday time settings | refactor payment scheduling

This commit is contained in:
JCEEE
2026-08-04 08:34:14 +01:00
parent ccbbd302d4
commit 85ea97ae96
16 changed files with 2877 additions and 659 deletions
@@ -16,7 +16,17 @@ export async function load(event) {
if (session.memberName && session.memberName !== username) {
throw redirect(303, `/${famSlug}/${session.memberName}`);
}
const [members, templates, assigned, summary, fam, rewards, bonusConfigs, completions] = await Promise.all([
const [
members,
templates,
assigned,
summary,
fam,
rewards,
bonusConfigs,
completions,
settings
] = await Promise.all([
hono.admin.list(event, 'members', famId),
hono.admin.list(event, 'chore-templates', famId),
hono.admin.list(event, 'assigned-chores', famId),
@@ -25,28 +35,68 @@ export async function load(event) {
hono.admin.rewards(event, famId),
hono.admin.bonusConfigs(event, famId),
hono.admin.completions(event, famId),
hono.admin.settings(event, famId).catch(() => ({}))
]);
return { role: 'parent', members, templates, assigned, summary, fam, famSlug, rewards, bonusConfigs, completions };
return {
role: 'parent',
members,
templates,
assigned,
summary,
fam,
famSlug,
rewards,
bonusConfigs,
completions,
settings
};
}
// Child (device token) → kanban
const deviceToken = event.cookies.get('device_token') || event.url.searchParams.get('token') || '';
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: {} };
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 }),
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: {} };
return {
role: 'child',
token: deviceToken,
memberId: '',
verified: false,
famId: '',
memberName: '',
memberColor: '',
templates: [],
assigned: [],
completions: [],
rewards: [],
bonusConfigs: [],
tallies: {}
};
}
let chores: any = {};
@@ -68,13 +118,55 @@ export async function load(event) {
rewards: chores.rewards || [],
bonusConfigs: chores.bonusConfigs || [],
tallies: chores.tallies || {},
payday: chores.payday,
paydayTime: chores.paydayTime || '18:00',
timezone: chores.timezone || 'auto'
};
} catch {
return { role: 'child', token: deviceToken, memberId: '', verified: false, famId: '', templates: [], assigned: [], completions: [], rewards: [], bonusConfigs: [], tallies: {} };
return {
role: 'child',
token: deviceToken,
memberId: '',
verified: false,
famId: '',
templates: [],
assigned: [],
completions: [],
rewards: [],
bonusConfigs: [],
tallies: {},
payday: 1,
paydayTime: '18:00',
timezone: 'auto'
};
}
}
export const actions = {
setEow: async (event) => {
if (!event.locals.session) throw redirect(303, '/login');
const famId = event.locals.session.famId;
const fd = await event.request.formData();
const on = fd.get('on') === 'true';
try {
const result = await hono.admin.updateSettings(event, famId, { simulateEow: on });
return { simulateEow: result.simulateEow };
} catch (e) {
return { error: e instanceof Error ? e.message : 'Failed to update settings' };
}
},
previewEow: async (event) => {
if (!event.locals.session) throw redirect(303, '/login');
const famId = event.locals.session.famId;
try {
const preview = await hono.admin.eowPreview(event, famId);
return { preview };
} catch (e) {
return { error: e instanceof Error ? e.message : 'Failed to preview payday' };
}
},
claim: async (event) => {
if (!event.locals.session) throw redirect(303, '/login');
const famId = event.locals.session.famId;
@@ -127,10 +219,15 @@ export const actions = {
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);
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' };
}
},
}
};