summaryrefslogtreecommitdiff
path: root/ping/frontend/src/routes/dashboard/personnel
diff options
context:
space:
mode:
Diffstat (limited to 'ping/frontend/src/routes/dashboard/personnel')
-rw-r--r--ping/frontend/src/routes/dashboard/personnel/+page.svelte290
1 files changed, 290 insertions, 0 deletions
diff --git a/ping/frontend/src/routes/dashboard/personnel/+page.svelte b/ping/frontend/src/routes/dashboard/personnel/+page.svelte
new file mode 100644
index 0000000..a1722c1
--- /dev/null
+++ b/ping/frontend/src/routes/dashboard/personnel/+page.svelte
@@ -0,0 +1,290 @@
+<script lang="ts">
+ import Avatar from '$lib/components/Avatar.svelte';
+ import UserItem from '$lib/components/UserItem.svelte';
+ import { authFetch, getUpdatedUser, getUser, type IUser } from '$lib/stores/auth';
+ import { addToast } from '$lib/stores/toast';
+ import { onMount } from 'svelte';
+
+ let user = $state<IUser | null>(null);
+ let allUsers = $state<IUser[]>([]);
+
+ let idValue = $state<string>('');
+ let urlValue = $state<string>('');
+ let nameValue = $state<string>('');
+ let passwordValue = $state<string>('');
+
+ async function loadUser() {
+ try {
+ user = await getUser();
+ if (!user) {
+ addToast({ title: 'Erreur', message: 'Utilisateur non trouvé.' });
+ return null;
+ }
+ idValue = user.id;
+ urlValue = user.avatar || '';
+ nameValue = user.displayName || '';
+ return user;
+ } catch (error) {
+ user = null;
+ addToast({ title: 'Erreur', message: 'Impossible de charger les informations utilisateur.' });
+ return null;
+ }
+ }
+
+ async function loadAllUsers() {
+ try {
+ const response = await authFetch('/api/user/all');
+ if (!response.ok) {
+ throw new Error('Erreur lors du chargement des utilisateurs');
+ }
+ const users = await response.json();
+ return users;
+ } catch (error) {
+ addToast({ title: 'Erreur', message: 'Impossible de charger la liste des utilisateurs.' });
+ return [];
+ }
+ }
+
+ function onEditUser(event: Event) {
+ event.preventDefault();
+ const form = event.target as HTMLFormElement;
+ const formData = new FormData(form);
+
+ const { id, avatar, username, password } = Object.fromEntries(formData.entries());
+
+ authFetch(`/api/user/${id}`, {
+ method: 'PUT',
+ body: JSON.stringify({
+ avatar: avatar || user?.avatar,
+ displayName: username || user?.displayName,
+ password: password || undefined
+ }),
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ })
+ .then((res) => res.json())
+ .then((data) => {
+ getUpdatedUser().then((updatedUser) => {
+ user = updatedUser;
+ });
+ console.log('Utilisateur mis à jour', data);
+ addToast({
+ title: 'Succès',
+ message: 'Informations utilisateur mises à jour avec succès.',
+ color: 'green'
+ });
+ })
+ .catch((error) => {
+ addToast({
+ title: 'Erreur',
+ message: 'Échec de la mise à jour des informations utilisateur.'
+ });
+ });
+ }
+
+ function onCreateUser(event: Event) {
+ event.preventDefault();
+ const form = event.target as HTMLFormElement;
+ const formData = new FormData(form);
+ const { login, password, isAdmin } = Object.fromEntries(formData.entries());
+
+ authFetch('/api/user', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ login,
+ password,
+ isAdmin: isAdmin === 'on'
+ })
+ })
+ .then(async (res) => {
+ if (!res.ok) {
+ addToast({
+ title: 'Erreur',
+ message: "Impossible de créer l'utilisateur."
+ });
+ throw new Error("Erreur lors de la création de l'utilisateur");
+ }
+ const newUser = await res.json();
+ allUsers = [...allUsers, newUser];
+ addToast({
+ title: 'Succès',
+ message: 'Nouvel utilisateur créé avec succès.',
+ color: 'green'
+ });
+ form.reset();
+ })
+ .catch(() => {
+ addToast({
+ title: 'Erreur',
+ message: "Impossible de créer l'utilisateur."
+ });
+ });
+ }
+
+ onMount(async () => {
+ loadUser().then((user) => {
+ if (user && user.isAdmin)
+ loadAllUsers().then((users) => {
+ allUsers = users;
+ });
+ });
+ });
+</script>
+
+{#if user}
+ <div id="personnel">
+ <div>
+ <section id="myUser" class="card">
+ <h2>Mon compte</h2>
+ <Avatar username={user.displayName} url={user.avatar || '/img/default-avatar.png'} />
+ <p><b>Nom</b>: {user.displayName}</p>
+ <p><b>Login</b>: {user.login}</p>
+ <p><b>Role</b>: {user.isAdmin ? 'ADMIN' : 'USER'}</p>
+ <p><b>Id</b>: {user.id}</p>
+ </section>
+ <section id="userEdit" class="card">
+ <h2>Modifier</h2>
+ <i
+ >Laisser vide pour ne pas modifier<br />
+ {#if user.isAdmin}
+ <p>Vous pouvez modifier les informations de n'importe quel utilisateur.</p>
+ {:else}
+ <p>Vous ne pouvez modifier que vos propres informations.</p>
+ {/if}
+ </i><br />
+ <form onsubmit={onEditUser}>
+ {#if user.isAdmin}
+ <label for="id">ID de l'utilisateur</label>
+ <input type="text" placeholder="ID de l'utilisateur" name="id" bind:value={idValue} />
+ {/if}
+ <label for="id">URL de l'avatar</label>
+ <input type="text" placeholder="URL de l'avatar" name="avatar" bind:value={urlValue} />
+ <label for="id">Nom d'utilisateur</label>
+ <input
+ type="text"
+ placeholder="Nom d'utilisateur"
+ name="username"
+ bind:value={nameValue}
+ />
+ <label for="id">Mot de passe</label>
+ <input
+ type="password"
+ placeholder="Mot de passe"
+ name="password"
+ bind:value={passwordValue}
+ />
+ <button type="submit" class="btn">Modifier</button>
+ </form>
+ </section>
+ </div>
+
+ {#if user.isAdmin}
+ <section id="adminActions">
+ <div class="card">
+ <h2>Créer un nouvel utilisateur</h2>
+ <form class="flex flex-col gap-2" onsubmit={onCreateUser}>
+ <label for="new-login">Login</label>
+ <input type="text" id="new-login" name="login" placeholder="Login" required />
+
+ <label for="new-password">Mot de passe</label>
+ <input
+ type="password"
+ id="new-password"
+ name="password"
+ placeholder="Mot de passe"
+ required
+ />
+
+ <label for="new-isAdmin">
+ <input type="checkbox" id="new-isAdmin" name="isAdmin" />
+ Administrateur
+ </label>
+
+ <button type="submit" class="btn">Créer</button>
+ </form>
+ </div>
+ <div class="card">
+ <h2>Liste des utilisateurs</h2>
+ <div>
+ {#each allUsers as u}
+ <UserItem
+ user={u}
+ onEdit={() => {
+ idValue = u.id;
+ urlValue = u.avatar || '';
+ nameValue = u.displayName || '';
+ }}
+ onDelete={() => {
+ authFetch(`/api/user/${u.id}`, {
+ method: 'DELETE'
+ })
+ .then(async (res) => {
+ if (!res.ok) {
+ addToast({
+ title: 'Erreur',
+ message: "Impossible de supprimer l'utilisateur."
+ });
+ throw new Error("Erreur lors de la suppression de l'utilisateur");
+ }
+ allUsers = allUsers.filter((user) => user.id !== u.id);
+ addToast({
+ title: 'Succès',
+ message: 'Utilisateur supprimé avec succès.',
+ color: 'green'
+ });
+ })
+ .catch(() => {
+ addToast({
+ title: 'Erreur',
+ message: "Impossible de supprimer l'utilisateur."
+ });
+ });
+ }}
+ />
+ {/each}
+ </div>
+ </div>
+ </section>
+ {/if}
+ </div>
+{:else}
+ <p>Chargement des informations utilisateur...</p>
+{/if}
+
+<style>
+ * {
+ color: white;
+ }
+
+ #personnel {
+ width: calc(100% - 32px);
+ display: flex;
+ gap: 16px;
+ }
+
+ #personnel > * {
+ flex: 1;
+ }
+
+ #myUser {
+ display: flex;
+ flex-direction: column;
+ }
+
+ #userEdit form {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ }
+
+ h2 {
+ margin: 0;
+ font-size: 1.5em;
+ font-weight: 600;
+ color: var(--text-lime);
+ }
+</style>