feat: implement automation key management with middleware and routes for organization API keys, invite improvements

This commit is contained in:
Rotimi Best
2026-03-13 18:40:07 +01:00
parent 77a1188573
commit 492f8dc5ed
71 changed files with 3655 additions and 456 deletions
@@ -17,6 +17,7 @@
import ShieldIcon from '@lucide/svelte/icons/shield';
const emailFromUrl = page.url.searchParams.get('email') ?? '';
const isEmailPrefilled = !!emailFromUrl;
let fields = $state(Object.assign({}, LOGIN_FIELDS, emailFromUrl ? { email: emailFromUrl } : {}));
@@ -192,7 +193,8 @@
bind:value={fields.email}
oninput={handleEmailChange}
placeholder="you@domain.com"
disabled={loading}
disabled={loading || isEmailPrefilled}
readonly={isEmailPrefilled}
autofocus
aria-invalid={errors.email ? 'true' : undefined}
autocomplete="username"
@@ -19,6 +19,7 @@
let { data } = $props();
const emailFromUrl = page.url.searchParams.get('email') ?? '';
const isEmailPrefilled = !!emailFromUrl;
let fields = $state(Object.assign({}, SIGNUP_FIELDS, emailFromUrl ? { email: emailFromUrl } : {}));
let loading = $state(false);
let errors: {
@@ -160,7 +161,8 @@
type="email"
bind:value={fields.email}
placeholder="you@domain.com"
disabled={loading}
disabled={loading || isEmailPrefilled}
readonly={isEmailPrefilled}
autofocus
aria-invalid={errors.email ? 'true' : undefined}
autocomplete="email"
@@ -45,6 +45,8 @@ export const load = async ({ params, url }) => {
course,
currentOrg,
invite: data.invite,
inviteEmail: data.inviteContext?.recipientEmail ?? null,
inviteEmailExists: data.inviteContext?.recipientExists ?? false,
requiresPaymentOrInvite: false,
token: inviteToken
};
@@ -64,7 +64,12 @@
const redirectUrl = `${redirectPath}${redirectSearch}`;
if (!$profile.id || !$profile.email) {
goto(resolve(`/signup?redirect=${encodeURIComponent(redirectUrl)}`, {}));
const inviteEmail = data.inviteEmail ?? '';
const target = data.inviteEmailExists ? '/login' : '/signup';
const params = new URLSearchParams({ redirect: redirectUrl });
if (inviteEmail) params.set('email', inviteEmail);
goto(resolve(`${target}?${params.toString()}`, {}));
loading = false;
return;
}
@@ -0,0 +1,22 @@
<script>
import { AutomationPage } from '$features/automation/pages';
import { t } from '$lib/utils/functions/translations';
import * as Page from '@cio/ui/base/page';
</script>
<svelte:head>
<title>{t.get('automation.title')} - ClassroomIO</title>
</svelte:head>
<Page.Header>
<Page.HeaderContent>
<Page.Title>{$t('automation.title')}</Page.Title>
<Page.Subtitle>{$t('automation.subtitle')}</Page.Subtitle>
</Page.HeaderContent>
</Page.Header>
<Page.Body>
{#snippet child()}
<AutomationPage />
{/snippet}
</Page.Body>