forked from Wroclaw/WorkshopTasker
125 lines
3.1 KiB
Vue
125 lines
3.1 KiB
Vue
|
<script setup lang="ts">
|
||
|
/* global $fetch */
|
||
|
import { useFetch, createError } from "nuxt/app";
|
||
|
import { ref, Ref } from "vue";
|
||
|
import { definePageMeta } from "~/.nuxt/imports";
|
||
|
import { client as clientType } from "~/utils/types/database";
|
||
|
|
||
|
definePageMeta({ middleware: ["auth"] });
|
||
|
|
||
|
const clientsRequest = await useFetch("/api/clients");
|
||
|
if (clientsRequest.error.value) throw createError(clientsRequest.error.value?.data ?? "");
|
||
|
const clients = clientsRequest.data as Ref<NonNullable<typeof clientsRequest.data.value>>;
|
||
|
|
||
|
const countRequest = await useFetch("/api/clients/count");
|
||
|
if (countRequest.error.value) throw createError(countRequest.error.value?.data ?? "");
|
||
|
const count = countRequest.data as Ref<NonNullable<typeof countRequest.data.value>>;
|
||
|
|
||
|
function rowClicked(client: string, edit = false) {
|
||
|
console.log(client);
|
||
|
}
|
||
|
|
||
|
async function rowDelete(client: string) {
|
||
|
try {
|
||
|
await $fetch<clientType>(`/api/clients/${client}`, {
|
||
|
method: "DELETE",
|
||
|
});
|
||
|
clients.value = clients.value.filter(e => e.id !== client);
|
||
|
count.value.count--;
|
||
|
} catch (e) {
|
||
|
// FIXME: show the error
|
||
|
console.log(e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const loadingMore = ref<boolean>(false);
|
||
|
async function loadBefore() {
|
||
|
loadingMore.value = true;
|
||
|
|
||
|
clients.value.push(...await $fetch("/api/clients", {
|
||
|
query: {
|
||
|
before: clients.value[clients.value.length - 1].id,
|
||
|
},
|
||
|
}));
|
||
|
loadingMore.value = false;
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
<template>
|
||
|
<VOverlay
|
||
|
model-value
|
||
|
origin="top center"
|
||
|
:scrim="false"
|
||
|
height="fit-content"
|
||
|
persistent
|
||
|
no-click-animation
|
||
|
>
|
||
|
<VAlert class="alert">
|
||
|
owowowowowowowowo
|
||
|
</VAlert>
|
||
|
</VOverlay>
|
||
|
<VRow>
|
||
|
<VCol>
|
||
|
<VBreadcrumbs :items="['Clients']" />
|
||
|
<VSpacer />
|
||
|
<div class="text-h4">
|
||
|
There are {{ count?.count }} clients in the database.
|
||
|
</div>
|
||
|
</VCol>
|
||
|
</VRow>
|
||
|
<VRow>
|
||
|
<VCol cols="12">
|
||
|
<VCard>
|
||
|
<VTable>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th>Name</th>
|
||
|
<th>Address</th>
|
||
|
<th />
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr v-for="client in clients" :key="client.id">
|
||
|
<td @click="() => rowClicked(client.id)">
|
||
|
{{ client.name }}
|
||
|
</td>
|
||
|
<td @click="() => rowClicked(client.id)">
|
||
|
{{ client.address }}
|
||
|
</td>
|
||
|
<td class="buttons">
|
||
|
<div>
|
||
|
<VBtn icon="mdi-pencil" variant="text" @click="() => rowClicked(client.id, true)" />
|
||
|
<VBtn icon="mdi-delete" color="red" variant="text" @click="() => rowDelete(client.id)" />
|
||
|
</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</VTable>
|
||
|
</VCard>
|
||
|
<VCol>
|
||
|
<VBtn
|
||
|
v-if="clients.length < count.count"
|
||
|
color="primary"
|
||
|
:loading="loadingMore"
|
||
|
@click="loadBefore"
|
||
|
>
|
||
|
Load more
|
||
|
</VBtn>
|
||
|
</VCol>
|
||
|
</VCol>
|
||
|
</VRow>
|
||
|
</template>
|
||
|
|
||
|
<style scoped>
|
||
|
.buttons {
|
||
|
width: 0;
|
||
|
padding-right: 4px !important;
|
||
|
}
|
||
|
.buttons > div {
|
||
|
display: flex;
|
||
|
flex-direction: row;
|
||
|
flex-wrap: nowrap;
|
||
|
}
|
||
|
|
||
|
</style>
|