feat(frontend): invite-based registration UI
Some checks failed
CI / Unit & Component Tests (push) Failing after 2m37s
CI / OCR Service Tests (push) Successful in 32s
CI / OCR Service Tests (pull_request) Successful in 30s
CI / Backend Unit Tests (push) Failing after 2m47s
CI / Unit & Component Tests (pull_request) Failing after 2m29s
CI / Backend Unit Tests (pull_request) Failing after 2m46s

- Add /register route with invite code prefill, password show/hide
- Add /login?registered=1 success banner
- Add /admin/invites page: list, create, revoke, copy link
- Add Einladungen nav section to admin sidebar (ADMIN_USER perm)
- Add invite error codes to errors.ts
- Add 48 i18n keys across de/en/es
- Update hooks.server.ts to allow public access to invite/register API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-19 01:01:19 +02:00
parent 61fa35df67
commit daea748a20
22 changed files with 953 additions and 21 deletions

View File

@@ -9,6 +9,7 @@ let {
userCount,
groupCount,
tagCount,
inviteCount,
canManageUsers,
canManageTags,
canManagePermissions,
@@ -17,6 +18,7 @@ let {
userCount: number;
groupCount: number;
tagCount: number;
inviteCount: number;
canManageUsers: boolean;
canManageTags: boolean;
canManagePermissions: boolean;
@@ -86,6 +88,23 @@ function handleKeydown(event: KeyboardEvent) {
</svg>
{/snippet}
{#snippet invitesIcon()}
<svg
class="h-5 w-5 flex-shrink-0 {isActive('invites') ? 'text-brand-mint' : 'text-white/40'}"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="1.5"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75"
/>
</svg>
{/snippet}
{#snippet tagsIcon()}
<svg
class="h-5 w-5 flex-shrink-0 {isActive('tags') ? 'text-brand-mint' : 'text-white/40'}"
@@ -180,6 +199,18 @@ function handleKeydown(event: KeyboardEvent) {
/>
{/if}
{#if canManageUsers}
<EntityNavSection
variant="sidebar"
href="/admin/invites"
label={m.admin_tab_invites()}
isActive={isActive('invites')}
count={inviteCount}
onTabletTrigger={openFlyout}
icon={invitesIcon}
/>
{/if}
{#if canManageTags}
<EntityNavSection
variant="sidebar"
@@ -264,6 +295,18 @@ function handleKeydown(event: KeyboardEvent) {
/>
{/if}
{#if canManageUsers}
<EntityNavSection
variant="flyout"
href="/admin/invites"
label={m.admin_tab_invites()}
isActive={isActive('invites')}
count={inviteCount}
onFlyoutClick={closeFlyout}
icon={invitesIcon}
/>
{/if}
{#if canManageTags}
<EntityNavSection
variant="flyout"