components/setters/UserSet.vue
<template>
<CardElt id="user-set">
<template #header>
<h2>
<i class="fa-solid fa-users-gear fa-lg"></i>
{{ val.USER_MANAGER }}
</h2>
</template>
<template #body>
<form enctype="multipart/form-data">
<TableElt :items="users">
<template #cell-id="slotProps">
<BtnElt :content="slotProps.item.id"
:href="`mailto:${slotProps.item.email}`"/>
</template>
<template #cell-name="slotProps">
<FieldElt :id="`name-${slotProps.item.id}`"
v-model:value="slotProps.item.name"
@keyup.enter="updateUser(slotProps.item.id)"
:info="val.INFO_UP_NAME">
<template #legend>{{ val.LEGEND_NAME }}</template>
<template #label>{{ val.LABEL_NAME }}</template>
</FieldElt>
</template>
<template #cell-email="slotProps">
<FieldElt :id="`email-${slotProps.item.id}`"
type="email"
v-model:value="slotProps.item.email"
@keyup.enter="updateUser(slotProps.item.id)"
:info="val.INFO_UP_EMAIL">
<template #legend>{{ val.LEGEND_EMAIL }}</template>
<template #label>{{ val.LABEL_EMAIL }}</template>
</FieldElt>
</template>
<template #cell-image="slotProps">
<MediaElt :src="'/img/thumbnails/users/' + slotProps.item.image"
:alt="slotProps.item.name"
:title="slotProps.item.image"
loading="lazy"/>
<FieldElt :id="`image-${slotProps.item.id}`"
type="file"
:info="val.INFO_UP_IMAGE">
<template #legend>{{ val.LEGEND_IMAGE }}</template>
<template #label>{{ val.LABEL_IMAGE }}</template>
</FieldElt>
</template>
<template #cell-role="slotProps">
<FieldElt :id="`role-${slotProps.item.id}`"
type="select"
:list="val.ROLES_USER"
v-model:value="slotProps.item.role"
@keyup.enter="updateUser(slotProps.item.id)"
:info="val.INFO_UP_ROLE">
<template #legend>{{ val.LEGEND_ROLE }}</template>
<template #label>{{ val.LABEL_ROLE }}</template>
</FieldElt>
</template>
<template #cell-createdAt="slotProps">
<p>{{ new Date(slotProps.item.createdAt).toLocaleString() }}</p>
<BtnElt type="button"
@click="deleteUser(slotProps.item.id)"
class="btn-red"
:title="val.TITLE_DELETE + slotProps.item.name">
<template #btn>
<i class="fa-solid fa-trash-arrow-up fa-lg fa-fw"></i>
</template>
</BtnElt>
</template>
<template #cell-updatedAt="slotProps">
<p>{{ new Date(slotProps.item.updatedAt).toLocaleString() }}</p>
<BtnElt type="button"
@click="updateUser(slotProps.item.id)"
class="btn-sky"
:title="val.TITLE_UPDATE + slotProps.item.name">
<template #btn>
<i class="fa-solid fa-cloud-arrow-up fa-lg fa-fw"></i>
</template>
</BtnElt>
</template>
</TableElt>
</form>
</template>
</CardElt>
</template>
<script>
import { checkRange, checkRegex, deleteData, getItemName, putData, setError } from "servidio"
import BtnElt from "../elements/BtnElt"
import CardElt from "../elements/CardElt"
import FieldElt from "../elements/FieldElt"
import MediaElt from "../elements/MediaElt"
import TableElt from "../elements/TableElt"
export default {
name: "UserSet",
components: { BtnElt, CardElt, FieldElt, MediaElt, TableElt },
props: ["token", "users", "val"],
data() {
return {
name: "",
email: "",
image:"",
pass: ""
}
},
methods: {
/**
* ? UPDATE USER
* * Update a user by their ID.
* @param {number} id - The ID of the user to update.
*/
updateUser(id) {
const { ALERT_UPDATED, API_URL, CHECK_EMAIL, CHECK_STRING, REGEX_EMAIL } = this.val;
const user = this.users.find(u => u.id === id);
let { name, email, image, role } = user;
const IS_NAME_CHECKED = user && checkRange(name, CHECK_STRING);
const IS_EMAIL_CHECKED = user && checkRegex(email, CHECK_EMAIL, REGEX_EMAIL);
if (IS_NAME_CHECKED && IS_EMAIL_CHECKED) {
const URL = `${API_URL}/users/${id}`;
const img = document.getElementById(`image-${id}`)?.files[0] ?? image;
const data = new FormData();
data.append("name", name);
data.append("email", email);
data.append("image", img);
data.append("role", role);
putData(URL, data, this.token)
.then(() => {
alert(name + ALERT_UPDATED);
this.$router.go();
})
.catch(err => setError(err));
}
},
/**
* ? DELETE USER
* * Delete a user by their ID.
* @param {number} id - The ID of the user to be deleted.
*/
deleteUser(id) {
const { TITLE_DELETE, API_URL, ALERT_DELETED } = this.val;
const NAME = getItemName(id, this.users);
if (confirm(`${TITLE_DELETE} ${NAME} ?`)) {
const URL = `${API_URL}/users/${id}`;
deleteData(URL, this.token)
.then(() => {
alert(NAME + ALERT_DELETED);
this.$router.push("/home");
})
.catch(err => setError(err));
}
}
}
}
</script>