0bd4e5498e
- portal: new admin/ and partner/ surfaces with full component library (AppLauncher, Avatar, Badge, Card, Modal, Tabs, etc.), composables, layouts, partner-routing middleware, and supporting server APIs - pricing: Price schema/module with operator CRUD, pricing.vue catalog UI, Subscription extended with cycle/currency/perSeatAmount/seats snapshots for stable MRR aggregation - partner staff: User.partnerId, invite-partner-user DTO and flow, /partners/:slug/users endpoints, InvitePartnerUserModal, shared dezky-partner-staff Authentik group - /me: partner-aware endpoint returning user + partner context so portal can route between end-user and partner-admin surfaces - tenant: seats field for portfolio displays and future MRR calculations - operator: pricing page, signed-out page, useMe/useToast composables, ToastStack
74 lines
1.5 KiB
Vue
74 lines
1.5 KiB
Vue
<script setup lang="ts">
|
|
// Interstitial login page. With customLoginPage:false in nuxt.config the
|
|
// OIDC module's route rule auto-redirects /auth/login → /auth/oidc/login,
|
|
// so this content rarely renders — it's a fallback for direct navigation.
|
|
|
|
definePageMeta({ auth: false, layout: 'blank' })
|
|
|
|
const email = ref('')
|
|
|
|
async function signIn() {
|
|
await navigateTo('/auth/oidc/login', { external: true })
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<AuthShell>
|
|
<AuthHeading
|
|
eyebrow="Sign in"
|
|
title="Welcome back"
|
|
body="Sign in to continue to your workspace."
|
|
/>
|
|
|
|
<form @submit.prevent="signIn">
|
|
<AuthInput
|
|
v-model="email"
|
|
label="Work email"
|
|
type="email"
|
|
placeholder="you@example.com"
|
|
mono
|
|
/>
|
|
<AuthButton type="submit" variant="primary">Continue with email</AuthButton>
|
|
</form>
|
|
|
|
<div class="divider">
|
|
<span class="line" />
|
|
<span class="or">OR</span>
|
|
<span class="line" />
|
|
</div>
|
|
|
|
<AuthButton variant="dark" @click="signIn">
|
|
<template #leading>
|
|
<UiIcon name="key" :size="14" />
|
|
</template>
|
|
Single sign-on (SSO)
|
|
</AuthButton>
|
|
|
|
<AuthFooterLink>
|
|
No account? Talk to your admin.
|
|
</AuthFooterLink>
|
|
</AuthShell>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.divider {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
margin: 18px 0;
|
|
}
|
|
|
|
.line {
|
|
flex: 1;
|
|
height: 1px;
|
|
background: var(--border);
|
|
}
|
|
|
|
.or {
|
|
font-family: var(--font-mono);
|
|
font-size: 10px;
|
|
color: var(--text-mute);
|
|
letter-spacing: 0.12em;
|
|
}
|
|
</style>
|