Merge pull request #113 from EETagent/user_delete

(frontend) delete user on dashboard
This commit is contained in:
Vojtěch Jungmann 2023-01-01 14:44:46 +01:00 committed by GitHub
commit a438091c99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 149 additions and 48 deletions

View file

@ -29,6 +29,16 @@ export const apiCreateCandidate = async (data: CreateCandidate): Promise<CreateC
}
};
// Deletes candidate /admin/candidate/{id}
export const apiDeleteCandidate = async (id: number): Promise<string> => {
try {
const res = await axios.delete(API_URL + `/admin/candidate/${id}`, { withCredentials: true });
return res.data;
} catch (e) {
throw errorHandler(e, 'Candidate creation failed');
}
};
// Reset candidate password /admin/candidate/{id}/reset_password
export const apiResetCandidatePassword = async (id: number): Promise<CreateCandidateLogin> => {
try {

View file

@ -0,0 +1,60 @@
<script lang="ts">
import Delete from '$lib/components/button/Delete.svelte';
import type { CandidatePreview } from '$lib/stores/candidate';
export let candidates: Array<CandidatePreview> = [];
</script>
<div class="flex flex-col">
<div class="overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="inline-block min-w-full py-4 sm:px-6 lg:px-8">
<div class="overflow-hidden rounded-md border-2 border-[#dfe0e9] ">
<table class="min-w-full text-center ">
<thead class="bg-[#f6f4f4] ">
<tr>
<th scope="col"> Ev. č. přihlásky </th>
<th scope="col"> Jméno </th>
<th scope="col"> Příjmení </th>
<th scope="col"> Obor </th>
<th scope="col" />
</tr>
</thead>
<tbody>
{#each candidates as candidate}
<tr class="border-b bg-white hover:cursor-pointer">
<td class="text-gray-900"
><a
target="_blank"
rel="noreferrer"
href="/admin/candidate/{candidate.applicationId}">{candidate.applicationId}</a
></td
>
<td class="text-gray-900">
{candidate.name}
</td>
<td class="text-gray-900">
{candidate.surname}
</td>
<td class="text-gray-900">
{candidate.study}
</td>
<td class="text-sm">
<Delete id={candidate.applicationId} on:delete value="Odstranit" />
</td>
</tr>
{/each}
</tbody>
</table>
</div>
</div>
</div>
</div>
<style lang="postcss">
th {
@apply px-6 py-4 text-sm font-medium text-gray-900;
}
td {
@apply whitespace-nowrap px-6 py-4 text-sm;
}
</style>

View file

@ -0,0 +1,65 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
export let value: string;
export let id: number | undefined;
let isPrepared = false;
const buttonLogic = () => {
if (isPrepared) {
dispatch('delete', {
id: id
});
} else {
dispatch('prepared', {
id: id
});
isPrepared = true;
setTimeout(() => {
isPrepared = false;
}, 3000);
}
};
</script>
<button on:click={buttonLogic} class="animate-bounce" class:isPrepared>
<svg
xmlns="http://www.w3.org/2000/svg"
class="mr-2 h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
{value}
</button>
<style lang="postcss">
button {
@apply inline-flex items-center;
@apply bg-red-700;
@apply @apply rounded-lg p-3 font-semibold
text-white transition-colors duration-300;
animation: none !important;
}
button:hover {
@apply bg-red-800;
}
.isPrepared {
@apply bg-red-800;
animation: bounce 1s infinite !important;
}
</style>

View file

@ -1,11 +1,13 @@
<script lang="ts">
import { apiListCandidates } from '$lib/@api/admin';
import { apiDeleteCandidate, apiListCandidates } from '$lib/@api/admin';
import Home from '$lib/components/icons/Home.svelte';
import TextField from '$lib/components/textfield/TextField.svelte';
import type { CandidatePreview } from '$lib/stores/candidate';
import CreateCandidateModal from '$lib/components/admin/CreateCandidateModal.svelte';
import Fuse from 'fuse.js';
import type { PageServerData } from './$types';
import Delete from '$lib/components/button/Delete.svelte';
import Table from '$lib/components/admin/table/Table.svelte';
export let data: PageServerData;
@ -13,7 +15,10 @@
const getCandidates = async (field?: string) => {
try {
candidates = await apiListCandidates(undefined, field);
candidates = await apiListCandidates(
undefined,
field ?? activeFilter !== 'Vše' ? activeFilter : ''
);
} catch {
console.log('error');
}
@ -23,7 +28,7 @@
let filters: Array<Filter> = ['Vše', 'KBB', 'IT', 'GYM'];
let activeFilter: Filter = 'Vše';
let activeFilter: Filter = filters[0];
const changeFilter = (filter: Filter) => {
activeFilter = filter;
@ -64,6 +69,11 @@
candidatesTable = fuse.search(searchValue).map((result) => result.item);
}
};
const deleteCandidate = async (id: number | undefined) => {
if (id) await apiDeleteCandidate(id);
getCandidates();
};
</script>
{#if createCandidateModal}
@ -103,51 +113,7 @@
</div>
{/if}
<div class="flex flex-col">
<div class="overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="inline-block min-w-full py-4 sm:px-6 lg:px-8">
<div class="overflow-hidden rounded-md border-2 border-[#dfe0e9] ">
<table class="min-w-full text-center ">
<thead class="bg-[#f6f4f4] ">
<tr>
<th scope="col" class="px-6 py-4 text-sm font-medium text-gray-900">
Ev. č. přihlásky
</th>
<th scope="col" class="px-6 py-4 text-sm font-medium text-gray-900"> Jméno </th>
<th scope="col" class="px-6 py-4 text-sm font-medium text-gray-900">
Příjmení
</th>
<th scope="col" class="px-6 py-4 text-sm font-medium text-gray-900"> Obor </th>
</tr>
</thead>
<tbody>
{#each candidatesTable as candidate}
<tr class="border-b bg-white hover:cursor-pointer">
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-900"
><a
target="_blank"
rel="noreferrer"
href="/admin/candidate/{candidate.applicationId}"
>{candidate.applicationId}</a
></td
>
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-900">
{candidate.name}
</td>
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-900">
{candidate.surname}
</td>
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-900">
{candidate.study}
</td>
</tr>
{/each}
</tbody>
</table>
</div>
</div>
</div>
</div>
<Table candidates={candidatesTable} on:delete={(event) => deleteCandidate(event.detail.id)} />
</div>
</div>
</div>