create-household flow via useAuth and Welcome page
This commit is contained in:
parent
ff8e665374
commit
44072a2363
4 changed files with 61 additions and 5 deletions
|
|
@ -81,11 +81,11 @@ This plan is adapted to the existing codebase, focusing on refactoring rather th
|
|||
- Ensures `activeHousehold` is set when navigating within a household.
|
||||
- **Nest existing routes**: Implemented behind feature flag.
|
||||
|
||||
3. **[ ] Implement Onboarding and Invitation Flows**:
|
||||
3. **[~] Implement Onboarding and Invitation Flows**:
|
||||
- Build the `Welcome.vue` view for creating the first household.
|
||||
- Build the `CreateAccount.vue` view.
|
||||
- Build the "Accept Invitation" page (`/invitations/accept?token=...`). It should take the token from the URL, call the API, and redirect on success.
|
||||
- Status: Placeholder views created for all three; logic pending. Household creation endpoint available.
|
||||
- Status: Welcome page now implements create-household flow using `POST /api/v1/households` and redirects to `/:slug/mealplan`. Create Account and Invitation Accept remain TODO.
|
||||
|
||||
4. **[~] Integrate Household Context into the App**:
|
||||
- **Create `src/composables/useHousehold.ts`**: Implemented. Extracts `householdSlug` from route and binds provider to API client.
|
||||
|
|
|
|||
|
|
@ -60,5 +60,15 @@ export function useAuth() {
|
|||
return hs
|
||||
}
|
||||
|
||||
return { user, households, activeHousehold, loadUser, login, loginWithPassword, logout, setHouseholds, setActiveHousehold, fetchHouseholds }
|
||||
async function createHousehold(name: string): Promise<Household> {
|
||||
const res = await api.POST('/api/v1/households', { body: { name } })
|
||||
if (!res.response.ok || !res.data) throw new Error('Failed to create household')
|
||||
const h: Household = { id: res.data.id, name: res.data.name, slug: res.data.slug }
|
||||
// Update local state: append and set active
|
||||
setHouseholds([...households.value, h])
|
||||
setActiveHousehold(h)
|
||||
return h
|
||||
}
|
||||
|
||||
return { user, households, activeHousehold, loadUser, login, loginWithPassword, logout, setHouseholds, setActiveHousehold, fetchHouseholds, createHousehold }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,35 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1>Welcome</h1>
|
||||
<p>Choose to create a new household or join via invitation link.</p>
|
||||
<section>
|
||||
<h2>Create a new household</h2>
|
||||
<form @submit.prevent="onCreate">
|
||||
<label for="name">Household Name</label>
|
||||
<input id="name" v-model="name" required />
|
||||
<button type="submit">Create</button>
|
||||
</form>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Join an existing household</h2>
|
||||
<p>To join a household, ask an existing member to send an invitation to your email address.</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// TODO: Implement onboarding flow per spec
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAuth } from '@/composables/useAuth'
|
||||
|
||||
const name = ref('')
|
||||
const router = useRouter()
|
||||
const { createHousehold } = useAuth()
|
||||
|
||||
async function onCreate() {
|
||||
const h = await createHousehold(name.value.trim())
|
||||
if (h?.slug) {
|
||||
router.push({ name: 'mealplan', params: { householdSlug: h.slug } })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
21
tests/households.create.test.ts
Normal file
21
tests/households.create.test.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { describe, it, expect } from 'vitest'
|
||||
import { server, http, HttpResponse } from './test-setup'
|
||||
import { useAuth } from '@/composables/useAuth'
|
||||
|
||||
describe('useAuth createHousehold', () => {
|
||||
it('creates a new household and sets activeHousehold', async () => {
|
||||
server.use(
|
||||
http.post('*/api/v1/households', async ({ request }) => {
|
||||
const body = await request.json()
|
||||
expect(body).toEqual({ name: 'The Smiths' })
|
||||
return HttpResponse.json({ id: 10, name: 'The Smiths', slug: 'the-smiths' })
|
||||
})
|
||||
)
|
||||
const { households, activeHousehold, createHousehold } = useAuth()
|
||||
expect(households.value).toEqual([])
|
||||
const h = await createHousehold('The Smiths')
|
||||
expect(h.slug).toBe('the-smiths')
|
||||
expect(activeHousehold.value?.slug).toBe('the-smiths')
|
||||
expect(households.value.find((x) => x.slug === 'the-smiths')).toBeTruthy()
|
||||
})
|
||||
})
|
||||
Loading…
Reference in a new issue