yale-user-access/packages/frontend/components/PeopleList.vue
Liam Pietralla f577617b4d
All checks were successful
Build and Publish / Build Yale Access Backend (push) Successful in 28s
Build and Publish / Build Yale Access Frontend (push) Successful in 47s
Build and Publish / Push Yale Access Backend Docker Image (push) Successful in 9s
Build and Publish / Push Yale Access Frontend Docker Image (push) Successful in 10s
initial commit
2025-01-10 08:37:18 +11:00

132 lines
3.7 KiB
Vue

<script setup lang="ts">
import { type Person } from '@/types/yale';
import { onMounted, ref } from 'vue';
import type { ApiResponse } from '~/types/api-response';
const people = ref([] as Person[]);
const person = ref({ id: 0, name: '', phoneNumber: '' } as Person);
const loading = ref(true);
const runtimeConfig = useRuntimeConfig();
const addModal = ref(false);
// When the component is mounted, load the people
onMounted(async () => {
await loadPeople();
loading.value = false;
});
const loadPeople = async () => {
// Send a request to the api to get the people
const response = await fetch(`${runtimeConfig.public.apiBaseUrl}/api/People`, { credentials: 'include' });
// Parse the response
const apiResponse = await response.json() as ApiResponse<Person[]>;
// Set the people
people.value = apiResponse.data || [];
}
const handleAddPerson = () => {
addModal.value = true;
}
const handleSavePerson = async () => {
// Validate the person fields
if (!person.value.name || !person.value.phoneNumber) {
alert('Name and phone number are required');
return;
}
// Set the loading status
loading.value = true;
// Send a request to the api to save the person
const response = await fetch(`${runtimeConfig.public.apiBaseUrl}/api/People`, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(person.value)
});
// Parse the response
const apiResponse = await response.json() as ApiResponse<Person>;
if (apiResponse.success) {
// Add the new person to the list
people.value.push(apiResponse.data!);
addModal.value = false;
} else {
alert(apiResponse.error ?? 'An error occurred');
}
// Close the modal and reset the person
loading.value = false;
person.value = { id: 0, name: '', phoneNumber: '' };
// Set the loading status
loading.value = false;
}
const handleDeletePerson = async (id: number) => {
// Set the loading status
loading.value = true;
// Send a request to the api to delete the person
const response = await fetch(`${runtimeConfig.public.apiBaseUrl}/api/People/${id}`, {
method: 'DELETE',
credentials: 'include'
});
// Parse the response
const apiResponse = await response.json() as ApiResponse<Person>;
if (apiResponse.success) {
// Remove the person from the list
const index = people.value.findIndex(x => x.id === id);
people.value.splice(index, 1);
} else {
alert(apiResponse.error ?? 'An error occurred');
}
// Set the loading status
loading.value = false;
}
</script>
<template>
<!-- Handle loading state -->
<div v-if="loading">Loading...</div>
<template v-else>
<div class="text-end my-2">
<YaleButton type="button" @click="handleAddPerson">Add Person</YaleButton>
</div>
<table class="w-full text-left">
<tr>
<th scope="col">Person ID</th>
<th scope="col">Name</th>
<th scope="col">Phone Number</th>
<th scope="col">Actions</th>
</tr>
<PeopleListRow v-for="person in people" :key="person.id" :person="person" @delete-person="handleDeletePerson" />
</table>
</template>
<!-- Add modal -->
<Modal v-if="addModal" @close="addModal = false">
<template #title>
Add Person
</template>
<template #default>
<div class="flex flex-col space-y-2">
<YaleFormInput v-model="person.name" type="text" placeholder="Name" class="block w-full" />
<YaleFormInput v-model="person.phoneNumber" type="text" placeholder="Phone" class="block w-full" />
<div class="flex justify-end">
<YaleButton type="button" @click="handleSavePerson">Save</YaleButton>
</div>
</div>
</template>
</Modal>
</template>