Refactored to show email/password form when multitenant flag is enabled; legacy person list retained otherwise. Link to Create Account added.

This commit is contained in:
jableader 2025-11-01 14:02:03 +11:00
parent 04dbddee44
commit ff8e665374
2 changed files with 74 additions and 24 deletions

View file

@ -199,7 +199,7 @@ SDK
- No path changes; ensure all calls work with new auth and household header.
UI
- Replace persons-based `LoginPage.vue` with email/password + Google; link to signup.
- Login Page: Refactored to show email/password form when multitenant flag is enabled; legacy person list retained otherwise. Link to Create Account added.
- Add `HouseholdSwitcher.vue` to app chrome and wire with router.
- Update components that navigate using string paths to use named routes with slug.

View file

@ -1,46 +1,92 @@
<template>
<div class="login">
<h1>Login Page</h1>
<ul class="button-group">
<li
v-for="(person, index) in persons"
:key="person.id ?? index"
>
<button
type="button"
class="btn btn-primary"
@click="onLogin(person)"
<h1>Login</h1>
<!-- Multitenant: Email/Password login -->
<div v-if="isMultitenant">
<form @submit.prevent="onSubmitLogin">
<div class="form-group">
<label for="email">Email</label>
<input id="email" v-model="email" type="email" required />
</div>
<div class="form-group">
<label for="password">Password</label>
<input id="password" v-model="password" type="password" required />
</div>
<button type="submit" class="btn btn-primary">Sign in</button>
<router-link class="btn btn-link" :to="{ name: 'create-account' }">Create account</router-link>
</form>
</div>
<!-- Legacy: Person quick-login list -->
<div v-else>
<ul class="button-group">
<li
v-for="(person, index) in persons"
:key="person.id ?? index"
>
{{ person.name }}
</button>
</li>
</ul>
<button
type="button"
class="btn btn-primary"
@click="onLegacyLogin(person)"
>
{{ person.name }}
</button>
</li>
</ul>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ref, onMounted, computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { getPersonsInHome } from '@/api/sdk'
import { login as loginApi } from '@/api/auth'
import { login as legacyLogin, loginWithPassword } from '@/api/auth'
import type { Person } from '@/domain/types'
import { useAuth } from '@/composables/useAuth'
const props = defineProps({
redirect: { type: String, default: '/' },
})
const router = useRouter()
const route = useRoute()
const persons = ref<Person[]>([])
const email = ref('')
const password = ref('')
const isMultitenant = computed(() => typeof process !== 'undefined' && process.env?.VUE_APP_MULTITENANT_ENABLED === 'true')
const { user } = useAuth()
onMounted(async () => {
const page = await getPersonsInHome()
persons.value = page.items
if (!isMultitenant.value) {
const page = await getPersonsInHome()
persons.value = page.items
}
})
async function onLogin(selectedPerson: Person) {
const person = await loginApi(selectedPerson.name)
if (person?.id >= 0) {
router.push(props.redirect)
function afterLoginNavigate() {
const redirectPath = (route.query?.redirect as string | undefined) || props.redirect
router.push(redirectPath || '/')
}
async function onSubmitLogin() {
try {
await loginWithPassword(email.value.trim(), password.value)
if (user.value?.id !== undefined) {
afterLoginNavigate()
return
}
alert('Login failed')
} catch (e) {
alert(e instanceof Error ? e.message : 'Login error')
}
}
async function onLegacyLogin(selectedPerson: Person) {
const u = await legacyLogin(selectedPerson.name)
if (u?.id !== undefined) {
afterLoginNavigate()
return
}
alert('Login failed')
@ -101,4 +147,8 @@ li:nth-child(4) > button {
background-color: #9a1f1f;
color: white;
}
.form-group {
margin-bottom: 12px;
}
</style>