Skip to content

Commit

Permalink
feat(admin): list refills for account
Browse files Browse the repository at this point in the history
  • Loading branch information
yyewolf committed Aug 9, 2023
1 parent a207853 commit 853b4d4
Show file tree
Hide file tree
Showing 4 changed files with 287 additions and 11 deletions.
245 changes: 245 additions & 0 deletions frontend/src/lib/components/admin/refills.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
<script lang="ts">
import { type Account, type Refill, RefillState } from '$lib/api';
import { refillsApi } from '$lib/requests/requests';
import { formatDate, formatPrice } from '$lib/utils';
import { onMount } from 'svelte';
onMount(() => {
reloadRefills();
});
let page = 0;
let max_page = 0;
let refills_per_page = 10;
let refills: Refill[] = [];
function reloadRefills() {
refillsApi()
.getAccountRefills(account.id, page, refills_per_page, undefined, undefined, {
withCredentials: true
})
.then((res) => {
refills = res.data.refills ?? [];
page = res.data.page;
max_page = res.data.max_page;
refills_per_page = res.data.limit;
})
.catch((err) => {
console.error(err);
});
}
function deleteRefill(id: string) {
refillsApi()
.markDeleteRefill(account.id, id, { withCredentials: true })
.then((res) => {
reloadRefills();
})
.catch((err) => {
console.error(err);
});
}
export let onClose: () => void;
export let account: Account;
</script>

<!-- Display a popup that asks for a pin -->

<button
id="overlay"
class="absolute w-full h-full top-0 left-0 bg-black bg-opacity-50 flex justify-center items-center z-40 hover:cursor-default"
on:click={() => {
onClose();
}}
/>

<div id="popup" class="absolute w-full h-full top-0 left-0 flex justify-center items-center">
<!-- Put a title and the numpad -->
<div class="flex flex-col items-center bg-white rounded-lg shadow-lg p-4 z-40">
<h1 class="text-2xl font-bold mb-4">Transactions du compte</h1>
<div class="flex flex-col items-center">
<!-- Table Section -->
<div class="max-w-[95%] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 mx-auto">
<!-- Card -->
<div class="flex flex-col">
<div class="-m-1.5 overflow-x-auto">
<div class="p-1.5 min-w-full inline-block align-middle">
<div
class="bg-white border border-gray-200 rounded-xl shadow-sm overflow-hidden dark:bg-slate-900 dark:border-gray-700"
>
<!-- Header -->
<div
class="px-6 py-4 grid gap-3 md:flex md:justify-between md:items-center border-b border-gray-200 dark:border-gray-700"
>
<div>
<h2 class="text-xl font-semibold text-gray-800 dark:text-gray-200">
Transactions
</h2>
</div>
</div>
</div>
<!-- End Header -->

<!-- Table -->
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-slate-800">
<tr>
<th scope="col" class="px-6 py-3 text-left">
<div class="flex items-center gap-x-2">
<span
class="text-xs font-semibold uppercase tracking-wide text-gray-800 dark:text-gray-200"
>
Date
</span>
</div>
</th>
<th scope="col" class="px-6 py-3 text-left">
<div class="flex items-center gap-x-2">
<span
class="text-xs font-semibold uppercase tracking-wide text-gray-800 dark:text-gray-200"
>
Emetteur
</span>
</div>
</th>
<th scope="col" class="px-6 py-3 text-left">
<div class="flex items-center gap-x-2">
<span
class="text-xs font-semibold uppercase tracking-wide text-gray-800 dark:text-gray-200"
>
Montant
</span>
</div>
</th>
<th scope="col" class="px-6 py-3 text-left">
<div class="flex items-center gap-x-2">
<span
class="text-xs font-semibold uppercase tracking-wide text-gray-800 dark:text-gray-200"
>
Etat
</span>
</div>
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200 dark:divide-gray-700">
{#each refills as refill}
<tr>
<td class="h-px w-72">
<div class="px-6 py-3">
<p class="text-sm dark:text-white/[.8] break-words p-2 bg-transparent">
{formatDate(refill.issued_at)}
</p>
</div>
</td>
<td class="h-px w-72">
<div class="px-6 py-3">
<p class="text-sm dark:text-white/[.8] break-words p-2 bg-transparent">
{refill.issued_by_name}
</p>
</div>
</td>
<td class="h-px w-72">
<div class="px-6 py-3">
<p class="text-sm dark:text-white/[.8] break-words p-2 bg-transparent">
{formatPrice(refill.amount)}
</p>
</div>
</td>
<td class="h-px w-72">
<div class="px-6 py-3">
<select
class="block text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
value={refill.state}
disabled
>
<option value="{RefillState.Valid}">Valide</option>
<option value="{RefillState.Canceled}">Annulé</option>
</select>
</div>
</td>
<td class="h-px w-px whitespace-nowrap">
<div class="px-6 py-1.5">
<button
class="inline-flex items-center gap-x-1.5 text-sm text-blue-600 decoration-2 hover:underline font-medium"
on:click={() => deleteRefill(refill.id)}
>
Supprimer
</button>
</div>
</td>
</tr>
{/each}
</tbody>
</table>
<!-- End Table -->

<!-- Footer -->
<div
class="px-6 py-4 grid gap-3 md:flex md:justify-between md:items-center border-t border-gray-200 dark:border-gray-700"
>
<div>
<div class="inline-flex gap-x-2">
<button
type="button"
class="py-2 px-3 inline-flex justify-center items-center gap-2 rounded-md border font-medium bg-white text-gray-700 shadow-sm align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-white focus:ring-blue-600 transition-all text-sm dark:bg-slate-900 dark:hover:bg-slate-800 dark:border-gray-700 dark:text-gray-400 dark:hover:text-white dark:focus:ring-offset-gray-800"
on:click={() => {
if (page > 0) {page--; reloadRefills();}
}}
>
<svg
class="w-3 h-3"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<path
fill-rule="evenodd"
d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"
/>
</svg>
Précédent
</button>

<p class="text-sm self-center text-gray-600 dark:text-gray-400">
Page {page + 1} / {max_page + 1}
</p>

<button
type="button"
class="py-2 px-3 inline-flex justify-center items-center gap-2 rounded-md border font-medium bg-white text-gray-700 shadow-sm align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-white focus:ring-blue-600 transition-all text-sm dark:bg-slate-900 dark:hover:bg-slate-800 dark:border-gray-700 dark:text-gray-400 dark:hover:text-white dark:focus:ring-offset-gray-800"
on:click={() => {
if (page < max_page) {page++; reloadRefills();}
}}
>
Suivant
<svg
class="w-3 h-3"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<path
fill-rule="evenodd"
d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"
/>
</svg>
</button>
</div>
</div>
</div>
<!-- End Footer -->
</div>
</div>
</div>
</div>
<!-- End Card -->
</div>
<!-- End Table Section -->
</div>
</div>
6 changes: 6 additions & 0 deletions frontend/src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
export const formatPrice = (price: number) => {
// Price is in cents, so we divide by 100 to get dollars
return `${(price / 100).toFixed(2)} €`;
}

export const formatDate = (date: number): string => {
// date is in unix seconds
const d = new Date(date * 1000);
return d.toLocaleDateString('fr-FR');
}
45 changes: 35 additions & 10 deletions frontend/src/routes/admin/accounts/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import type { Account, NewAccount, NewCategory } from '$lib/api';
import { api } from '$lib/config/config';
import Refills from '$lib/components/admin/refills.svelte';
import { accountsApi } from '$lib/requests/requests';
import { formatPrice } from '$lib/utils';
import { onMount } from 'svelte';
Expand All @@ -20,6 +20,7 @@
let page = 0;
let max_page = 0;
let accounts_per_page = 10;
let shown_refill: Account | undefined = undefined;
onMount(() => {
reloadAccounts();
Expand Down Expand Up @@ -64,6 +65,15 @@
}
</script>

{#if shown_refill}
<Refills
account={shown_refill}
onClose={() => {
shown_refill = undefined;
}}
/>
{/if}

<!-- Popup -->
<div
id="hs-modal-new-account"
Expand Down Expand Up @@ -231,6 +241,17 @@
accept=".csv"
on:change={(e) => importAccounts(e)}
/>
<button
class="py-2 px-3 inline-flex justify-center items-center gap-2 rounded-md border border-transparent font-semibold bg-blue-500 text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-all text-sm dark:focus:ring-offset-gray-800"
on:click={() => {
// @ts-ignore
document.getElementById('import').click();
}}
>
Importer des Comptes
</button>


<button
class="py-2 px-3 inline-flex justify-center items-center gap-2 rounded-md border border-transparent font-semibold bg-blue-500 text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-all text-sm dark:focus:ring-offset-gray-800"
data-hs-overlay="#hs-modal-new-account"
Expand Down Expand Up @@ -326,7 +347,7 @@
<div class="px-6 py-3">
<input
type="text"
class="block text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
class="block text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
value={account.last_name}
on:input={(e) => {
// @ts-ignore
Expand All @@ -353,7 +374,7 @@
<div class="px-6 py-3">
<input
type="text"
class="block text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
class="block text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
value={account.first_name}
on:input={(e) => {
// @ts-ignore
Expand All @@ -380,7 +401,7 @@
<div class="px-6 py-3">
<input
type="text"
class="w-72 block text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
class="w-72 block text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
value={account.email_address}
on:input={(e) => {
// @ts-ignore
Expand All @@ -405,17 +426,15 @@
</td>
<td class="h-px w-72">
<div class="px-6 py-3">
<p
class="text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
>
<p class="text-sm dark:text-white/[.8] break-words p-2 bg-transparent">
{formatPrice(account.balance)}
</p>
</div>
</td>
<td class="h-px w-72">
<div class="px-6 py-3">
<select
class="block text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
class="block text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
value={account.role}
on:change={(e) => {
// @ts-ignore
Expand Down Expand Up @@ -448,7 +467,7 @@
<td class="h-px w-72">
<div class="px-6 py-3">
<select
class="block text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
class="block text-sm dark:text-white/[.8] break-words p-2 bg-transparent"
value={account.price_role}
on:change={(e) => {
// @ts-ignore
Expand Down Expand Up @@ -479,6 +498,12 @@
</td>
<td class="h-px w-px whitespace-nowrap">
<div class="px-6 py-1.5">
<button
class="inline-flex items-center gap-x-1.5 text-sm text-blue-600 decoration-2 hover:underline font-medium"
on:click={() => shown_refill = account}
>
Transactions
</button>
<button
class="inline-flex items-center gap-x-1.5 text-sm text-blue-600 decoration-2 hover:underline font-medium"
on:click={() => deleteAccount(account.id)}
Expand Down Expand Up @@ -537,7 +562,7 @@
type="button"
class="py-2 px-3 inline-flex justify-center items-center gap-2 rounded-md border font-medium bg-white text-gray-700 shadow-sm align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-white focus:ring-blue-600 transition-all text-sm dark:bg-slate-900 dark:hover:bg-slate-800 dark:border-gray-700 dark:text-gray-400 dark:hover:text-white dark:focus:ring-offset-gray-800"
on:click={() => {
if (page < Math.ceil(accounts.length / accounts_per_page) - 1) page++;
if (page < max_page) page++;
}}
>
Suivant
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/admin/restore/accounts/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@
type="button"
class="py-2 px-3 inline-flex justify-center items-center gap-2 rounded-md border font-medium bg-white text-gray-700 shadow-sm align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-white focus:ring-blue-600 transition-all text-sm dark:bg-slate-900 dark:hover:bg-slate-800 dark:border-gray-700 dark:text-gray-400 dark:hover:text-white dark:focus:ring-offset-gray-800"
on:click={() => {
if (page < Math.ceil(accounts.length / accounts_per_page) - 1) page++;
if (page < max_page) page++;
}}
>
Suivant
Expand Down

0 comments on commit 853b4d4

Please sign in to comment.