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. - No path changes; ensure all calls work with new auth and household header.
UI 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. - Add `HouseholdSwitcher.vue` to app chrome and wire with router.
- Update components that navigate using string paths to use named routes with slug. - Update components that navigate using string paths to use named routes with slug.

View file

@ -1,6 +1,24 @@
<template> <template>
<div class="login"> <div class="login">
<h1>Login Page</h1> <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"> <ul class="button-group">
<li <li
v-for="(person, index) in persons" v-for="(person, index) in persons"
@ -9,38 +27,66 @@
<button <button
type="button" type="button"
class="btn btn-primary" class="btn btn-primary"
@click="onLogin(person)" @click="onLegacyLogin(person)"
> >
{{ person.name }} {{ person.name }}
</button> </button>
</li> </li>
</ul> </ul>
</div> </div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue' import { ref, onMounted, computed } from 'vue'
import { useRouter } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { getPersonsInHome } from '@/api/sdk' 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 type { Person } from '@/domain/types'
import { useAuth } from '@/composables/useAuth'
const props = defineProps({ const props = defineProps({
redirect: { type: String, default: '/' }, redirect: { type: String, default: '/' },
}) })
const router = useRouter() const router = useRouter()
const route = useRoute()
const persons = ref<Person[]>([]) 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 () => { onMounted(async () => {
if (!isMultitenant.value) {
const page = await getPersonsInHome() const page = await getPersonsInHome()
persons.value = page.items persons.value = page.items
}
}) })
async function onLogin(selectedPerson: Person) { function afterLoginNavigate() {
const person = await loginApi(selectedPerson.name) const redirectPath = (route.query?.redirect as string | undefined) || props.redirect
if (person?.id >= 0) { router.push(redirectPath || '/')
router.push(props.redirect) }
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 return
} }
alert('Login failed') alert('Login failed')
@ -101,4 +147,8 @@ li:nth-child(4) > button {
background-color: #9a1f1f; background-color: #9a1f1f;
color: white; color: white;
} }
.form-group {
margin-bottom: 12px;
}
</style> </style>