add new GDPR page and handle account creation email

This commit is contained in:
JCEEE
2026-09-08 15:20:34 +01:00
parent 9117c0ec70
commit afc463a0f0
8 changed files with 406 additions and 14 deletions
+27 -1
View File
@@ -6,6 +6,7 @@ import { setSessionCookie } from '$lib/server/session';
import { issueAccess } from '$lib/server/member-otp';
import { slugify, handle, famUsername, handleOf } from '@shared/slugify';
import { applyAccessCode } from '$lib/server/access';
import { sendWelcomeEmail, sendAccessUnlockedEmail } from '$lib/server/email';
import { createEmbeddedCheckoutSession, PLAN_IDS } from '$lib/server/stripe';
import type { PlanId } from '$lib/server/stripe';
@@ -70,6 +71,10 @@ export const actions = {
.catch(() => null);
if (authResult?.token) setSessionCookie(event.cookies, authResult.token);
// Welcome email — a best-effort send. Failures must not block signup.
const dashboardUrl = `${event.url.origin}/${slug}`;
sendWelcomeEmail({ to: email, famName, dashboardUrl }).catch(() => {});
return { success: true, famSlug: slug, username: handleName };
},
@@ -111,6 +116,27 @@ export const actions = {
const result = await applyAccessCode(user.famId, code);
if (result.error) return fail(400, { error: result.error });
// Access code applied successfully — confirm by email (best-effort).
// Failure must never block the user continuing to the plan step.
if (result.ok) {
const fam = await pbAdmin
.getOne('fams', user.famId)
.catch(() => ({ name: '', slug: user.famId }));
const parents = await pbAdmin
.getList('users', `famId = '${user.famId}' && role = 'parent'`)
.catch(() => []);
const parentEmail = (parents[0] as { email?: string } | undefined | null)?.email;
if (parentEmail) {
sendAccessUnlockedEmail({
to: parentEmail,
famName: fam.name || '',
codeName: result.code?.name || code,
codeValue: code,
dashboardUrl: `${event.url.origin}/${fam.slug || user.famId}`
}).catch(() => {});
}
}
return { ok: true, ...result };
},
@@ -148,4 +174,4 @@ export const actions = {
function requireUser(event: RequestEvent) {
if (!event.locals.user) throw redirect(303, '/signup');
return event.locals.user;
}
}
+19
View File
@@ -189,6 +189,10 @@
/>
</label>
<button type="submit" disabled={submitting}>Create my family</button>
<p class="privacy-note">
By signing up you agree to our <a href="/privacy">Privacy Policy</a>. We collect your email
only to create and log into your account, never sell or share your data.
</p>
</form>
<p class="alt">Already have a family? <a href="/login">Log in</a></p>
{:else if step === 'child'}
@@ -381,6 +385,21 @@
font-size: 0.85rem;
color: #059669;
}
.privacy-note {
margin: 0.25rem 0 0;
font-size: 0.78rem;
color: #6b7280;
line-height: 1.5;
text-align: center;
}
.privacy-note a {
color: #4338ca;
text-decoration: none;
font-weight: 500;
}
.privacy-note a:hover {
text-decoration: underline;
}
.actions {
margin-top: 1.25rem;
}