refactor invitation handling: remove email parameter from createInviteLink and update UI to use invite link

This commit is contained in:
jableader 2025-12-13 15:35:30 +11:00
parent 4edeb6dfe4
commit e873bbc3f8
4 changed files with 19 additions and 73 deletions

View file

@ -14,21 +14,13 @@ export async function acceptInvitation(token: string): Promise<Household> {
return { id: h.id, name: h.name, slug: h.slug }
}
export async function sendInvitation(householdSlug: string, email: string): Promise<void> {
const res = await api.POST('/api/v1/households/{householdSlug}/invitations', {
params: { path: { householdSlug } },
body: { email },
})
if (!res.response.ok) throw new Error(`${res.response.status} ${res.response.statusText || 'HTTP error'}`)
}
export async function createInviteLink(householdSlug: string): Promise<string> {
const { data, error, response } = await api.POST('/api/v1/households/{householdSlug}/invitations', { params: { path: { householdSlug } } })
export async function createInviteLink(householdSlug: string, email: string): Promise<string> {
const res = await api.POST('/api/v1/households/{householdSlug}/invitations', {
params: { path: { householdSlug } },
body: { email },
})
if (!res.response.ok) throw new Error(`${res.response.status} ${res.response.statusText || 'HTTP error'}`)
const inviteLink = res.data?.invite_link
if (!response.ok) {
throw new Error(`${response.status} ${response.statusText || 'HTTP error'}${error ? `: ${String(error)}` : ''}`)
}
const inviteLink = data?.invite_link
if (typeof inviteLink !== 'string') throw new Error('Invalid response: missing invite_link')
return inviteLink
}

View file

@ -462,11 +462,6 @@ export interface components {
/** Name */
name: string;
};
/** CreateInvitationBody */
CreateInvitationBody: {
/** Email */
email: string;
};
/** CurrentShoppingList */
CurrentShoppingList: {
/** Outstandingitems */
@ -1341,11 +1336,7 @@ export interface operations {
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["CreateInvitationBody"];
};
};
requestBody?: never;
responses: {
/** @description Successful Response */
200: {

View file

@ -3,29 +3,14 @@
<h1>Household Members</h1>
<section>
<h2>Invite a member</h2>
<form @submit.prevent="onInvite">
<label for="email">Email</label>
<input
id="email"
v-model="email"
type="email"
required
autocomplete="email"
>
<button
type="submit"
:disabled="submitting"
>
Send Invitation
</button>
<button
type="button"
:disabled="submitting"
@click="onCopyInviteLink"
>
Copy Invite Link
</button>
</form>
<p class="muted">Share an invite link with the person you want to add.</p>
<button
type="button"
:disabled="submitting"
@click="onCopyInviteLink"
>
Copy Invite Link
</button>
<p
v-if="message"
class="message"
@ -62,12 +47,11 @@
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { sendInvitation, createInviteLink } from '@/api/invitations'
import { createInviteLink } from '@/api/invitations'
import { listMembers, type Member } from '@/api/households'
import { useRoute } from 'vue-router'
import { useAlert } from '@/composables/useAlert'
const email = ref('')
const submitting = ref(false)
const message = ref('')
const error = ref('')
@ -84,23 +68,6 @@ onMounted(async () => {
}
})
async function onInvite() {
message.value = ''
error.value = ''
submitting.value = true
try {
const slug = householdSlug.value
if (!slug) throw new Error('No household selected')
await sendInvitation(slug, email.value.trim())
message.value = 'Invitation sent.'
email.value = ''
} catch (e) {
error.value = e instanceof Error ? e.message : 'Failed to send invitation'
} finally {
submitting.value = false
}
}
async function onCopyInviteLink() {
message.value = ''
error.value = ''
@ -108,15 +75,11 @@ async function onCopyInviteLink() {
try {
const slug = householdSlug.value
if (!slug) throw new Error('No household selected')
const emailValue = email.value.trim()
if (!emailValue) throw new Error('Please enter an email address')
const inviteLink = await createInviteLink(slug, emailValue)
const inviteLink = await createInviteLink(slug)
await navigator.clipboard.writeText(inviteLink)
showAlert({ type: 'success', heading: 'Success', message: 'Invite link copied to clipboard!' })
scheduleAutoDismiss(3000)
email.value = ''
} catch (e) {
error.value = e instanceof Error ? e.message : 'Failed to copy invite link'
} finally {

View file

@ -17,7 +17,7 @@
</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>
<p>To join a household, ask an existing member to share an invitation link with you.</p>
</section>
</div>
</template>