The issue is that the form data is not being passed to the createMember action. To fix this, you need to bind the form inputs to data properties and pass them as arguments to the createMember action. Here's how you can modify the code:
- Add data properties for the form inputs in the component:
data() {
return {
name: '',
email: '',
status: 'active',
};
},
- Bind the form inputs to the data properties using
v-model:
<input type="text" id="name" class="border border-gray-300 px-4 py-2 rounded" v-model="name" />
<input type="email" id="email" class="border border-gray-300 px-4 py-2 rounded" v-model="email" />
<select id="status" class="border border-gray-300 px-4 py-2 rounded" v-model="status">
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
- Pass the data properties as arguments to the
createMemberaction:
<form class="flex flex-col gap-y-4" @submit.prevent="team.createMember(name, email, status)">
Note that we're using @submit.prevent to prevent the default form submission behavior and passing the data properties as arguments to the createMember action.
Here's the modified code for the component:
<template>
<Modal :show="showModal" @close="showModal = false">
<template #default>
<h2 class="text-2xl font-bold mb-2">Add a new member</h2>
<form class="flex flex-col gap-y-4" @submit.prevent="team.createMember(name, email, status)">
<div class="flex flex-col gap-y-1">
<label for="name" class="text-lg font-medium">Name</label>
<input type="text" id="name" class="border border-gray-300 px-4 py-2 rounded" v-model="name" />
</div>
<div class="flex flex-col gap-y-1">
<label for="email" class="text-lg font-medium">Email</label>
<input type="email" id="email" class="border border-gray-300 px-4 py-2 rounded" v-model="email" />
</div>
<div class="flex flex-col gap-y-1">
<label for="status" class="text-lg font-medium">Status</label>
<select id="status" class="border border-gray-300 px-4 py-2 rounded" v-model="status">
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</div>
<button type="submit" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">Add Member</button>
</form>
</template>
</Modal>
</template>
<script>
export default {
data() {
return {
name: '',
email: '',
status: 'active',
};
},
props: {
showModal: Boolean,
},
inject: ['team'],
};
</script>
And here's the modified code for the TeamStore.js:
export let useTeamStore = defineStore("team", {
state: () => ({
name: "",
max: 1,
avatar: "",
members: [],
}),
actions: {
// async will only fill the store once the view is mounted & the action is called
async fill() {
let data = await import("@/team.json");
this.$state = data.default;
},
addSpots(number) {
this.max += number;
flashMessage("The team size is increased", "success");
},
createMember(name, email, status) {
console.log("createMember", name, email, status);
if (this.members.length === this.max) {
flashMessage("The team is full", "error");
} else {
// work out what the next id is
let ids = this.members.map((m) => m.id);
let max = Math.max(...ids);
let member = {};
// create the member
member.id = max + 1;
member.name = name;
member.email = email;
member.status = status;
member.avatar = `https://api.adorable.io/avatars/285/${member.email}.png`;
this.members.push(member);
flashMessage("The team member is