send email on claim requests
This commit is contained in:
@@ -127,3 +127,32 @@ export async function sendMentionEmail(opts: {
|
||||
`
|
||||
});
|
||||
}
|
||||
|
||||
// A child asked to collect a reward — ping the parent(s) with the ask and a
|
||||
// link straight to the Claims card on the admin dashboard.
|
||||
export async function sendClaimRequestEmail(opts: {
|
||||
to: string;
|
||||
parentName: string;
|
||||
childName: string;
|
||||
rewardName: string;
|
||||
rewardValue: string;
|
||||
dashboardUrl: string;
|
||||
}) {
|
||||
const { to, parentName, childName, rewardName, rewardValue, dashboardUrl } = opts;
|
||||
|
||||
await resend.emails.send({
|
||||
from: 'no-reply@walthamstow.xyz',
|
||||
to,
|
||||
subject: `${childName} asked to claim ${rewardName}`,
|
||||
html: `
|
||||
<p>Hi ${escHtml(parentName)},</p>
|
||||
<p><strong>${escHtml(childName)}</strong> asked to collect a reward:</p>
|
||||
<p>
|
||||
<strong>${escHtml(rewardName)}</strong>
|
||||
${rewardValue ? `— ${escHtml(rewardValue)}` : ''}
|
||||
</p>
|
||||
<p><a href="${dashboardUrl}">Open the Claims card on your dashboard</a> to review and issue it.</p>
|
||||
<p>Talk soon,<br />The FamDone team</p>
|
||||
`
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import type { RequestEvent } from '@sveltejs/kit';
|
||||
import { createPbClient } from '$lib/server/pocketbase';
|
||||
import { createPbClient, pbAdmin } from '$lib/server/pocketbase';
|
||||
import { createServices } from '$lib/server/services';
|
||||
import { sendClaimRequestEmail } from '$lib/server/email';
|
||||
import { handleOf } from '@shared/slugify';
|
||||
|
||||
export async function POST(event: RequestEvent) {
|
||||
const u = event.locals.user;
|
||||
@@ -10,7 +12,35 @@ export async function POST(event: RequestEvent) {
|
||||
const id = event.params.id!;
|
||||
try {
|
||||
const s = createServices(pb, { id: u.id, role: u.role });
|
||||
return json(await s.rewards.claim(u.famId, id));
|
||||
const record = await s.rewards.claim(u.famId, id);
|
||||
|
||||
// Tell the parent(s) a claim was requested — best-effort, so a mail
|
||||
// outage can never fail the claim itself.
|
||||
try {
|
||||
const [parents, fam] = await Promise.all([
|
||||
pbAdmin.getList('users', `famId = '${u.famId}' && role = 'parent'`),
|
||||
pbAdmin.getOne('fams', u.famId)
|
||||
]);
|
||||
const label = record?.label || 'a reward';
|
||||
const idx = label.indexOf(' – ');
|
||||
const rewardName = idx === -1 ? label : label.slice(0, idx);
|
||||
const rewardValue = idx === -1 ? '' : label.slice(idx + 3);
|
||||
for (const parent of parents) {
|
||||
if (!parent.email) continue;
|
||||
await sendClaimRequestEmail({
|
||||
to: parent.email,
|
||||
parentName: parent.name || 'there',
|
||||
childName: u.name || 'Someone',
|
||||
rewardName,
|
||||
rewardValue,
|
||||
dashboardUrl: `${event.url.origin}/${fam?.slug || u.famId}/${handleOf(parent.username)}`
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// Best-effort only — the claim already succeeded.
|
||||
}
|
||||
|
||||
return json(record);
|
||||
} catch (e) {
|
||||
return json({ error: e instanceof Error ? e.message : 'claim failed' }, { status: 400 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user