generateur_v3/frontend/src/components/rooms/Members.svelte

249 lines
5.9 KiB
Svelte

<script lang="ts">
import type { Member, Room, Waiter } from "../../types/room.type";
import FaUnlock from "svelte-icons/fa/FaUnlock.svelte";
import FaLock from "svelte-icons/fa/FaLock.svelte";
import { getContext } from "svelte";
import type { Writable } from "svelte/store";
import FaTimes from "svelte-icons/fa/FaTimes.svelte";
import FaCheck from "svelte-icons/fa/FaCheck.svelte";
import MdCheck from "svelte-icons/md/MdCheck.svelte";
import MdClose from "svelte-icons/md/MdClose.svelte";
const room: Writable<Room> = getContext("room");
const member: Writable<Member> = getContext("member");
const { send } = getContext<{ send: Function }>("ws");
const { alert } = getContext<{ alert: Function }>("alert");
$: online =
$room != null
? $room.members.filter((r): r is Member => "online" in r && r.online == true)
: [];
$: offline =
$room != null
? $room.members.filter((r): r is Member => "online" in r && r.online == false)
: [];
$: waiters =
$room != null
? $room.members.filter((r): r is Waiter => "waiter_id" in r && !!r.waiter_id)
: [];
const ban = (m: Member) => {
if (!$member.isAdmin || m.isAdmin) return;
alert(
{
title: "Bannir", description: "Êtes-vous sûr de vouloir bannir cet utilisateur ?", validate: () => {
send("ban", { member_id: m.id_code });
}, validateButton: "Bannir"
}
);
};
</script>
<div class="members">
<div class="head">
<h2>Participants</h2>
{#if !!$member.isAdmin}
<div
data-testid="visibilityChange"
class:public={$room.public}
class:private={!$room.public}
class="icon"
on:click={() => {
send('set_visibility', { public: !$room.public });
}}
on:keydown={() => {}}
>
{#if $room.public}
<div data-testid="public">
<FaUnlock
title="Rendre la salle privée (vous devrez accepter chaque personne voulant entrer)"
/>
</div>
{:else}
<div data-testid="private">
<FaLock title="Rendre la salle ouverte (tout personne ayant le code pourra entrer librement)" />
</div>
{/if}
</div>
{/if}
</div>
<div>
<h3>En ligne :</h3>
{#each online as m}
<p
class:admin={m.isAdmin}
class:bannable={m.id_code != $member.id_code && $member.isAdmin && !m.isAdmin}
class:member={m.id_code == $member.id_code}
class="online"
title={$member.isAdmin && !m.isAdmin ? 'Bannir' : ''}
on:click={(e)=>ban(m)}
on:keydown={() => {}}
>
{m.username}
{#if m.reconnect_code != '' && ($member.isAdmin || m.id_code == $member.id_code)}
<span>#{m.reconnect_code}</span>
{/if}
{#if m.isAdmin}
<span class="admin-mark">Administrateur</span>
{/if}
</p>
{/each}
{#if offline.length > 0}
<h3>Hors-ligne :</h3>
{#each offline as m}
<p
class:admin={m.isAdmin}
class="offline"
class:bannable={m.id_code != $member.id_code && $member.isAdmin && !m.isAdmin}
class:member={m.id_code == $member.id_code}
title={$member.isAdmin && !m.isAdmin ? 'Bannir' : ''}
on:click={(e)=>ban(m)}
on:keydown={() => {}}
>
{m.username}
{#if (m.reconnect_code != '' && $member.isAdmin) || m.id_code == $member.id_code}
<span>#{m.reconnect_code}</span>
{/if}
{#if m.isAdmin}
<span class="admin-mark">Administrateur</span>
{/if}
</p>
{/each}
{/if}
{#if $member.isAdmin && waiters.length > 0}
<h3>Liste d'attente :</h3>
{#each waiters as m}
<p>
{m.username}<span>#{m.waiter_id}</span>
<button
class="accept"
on:click={() => {
send('accept', { waiter_id: m.waiter_id });
}}
title="Accepter"
>
<MdCheck />
</button
>
<button
class="refuse"
on:click={() => {
send('refuse', { waiter_id: m.waiter_id });
}}
title="Refuser"
>
<MdClose />
</button
>
</p>
{/each}
{/if}
</div>
</div>
<style lang="scss">
.head {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
border-bottom: 1px solid $border;
.icon {
width: 20px;
height: 20px;
cursor: pointer;
}
h2 {
font-size: 1.2em;
font-weight: 900;
padding: 10px;
padding-top: 0;
padding-left: 0;
}
}
.members {
background-color: rgba($background, 0.4);
border: 1px solid $border;
border-radius: 6px;
padding: 20px 15px;
width: 100%;
min-height: 70%;
max-height: 100%;
h3 {
font-size: 1em;
font-weight: 700;
margin: 10px 0;
}
p {
cursor: pointer;
margin-left: 15px;
font-size: 1em;
width: max-content;
display: flex;
align-items: center;
span {
color: grey;
font-size: 0.9em;
margin-left: 3px;
}
margin-bottom: 4px;
}
.bannable:hover {
text-decoration: line-through;
color: $red;
font-weight: 700;
}
.offline {
color: rgb(178, 176, 176);
}
.member {
font-weight: 900;
}
}
.admin-mark {
border-radius: 3px;
background-color: $contrast;
padding: 3px;
color: #f8f8f8 !important;
font-weight: 500;
font-size: 0.8em !important;
}
.accept, .refuse {
border: none;
background-color: transparent;
cursor: pointer;
width: 30px;
height: 30px;
transition: .3s;
margin: 0;
&:hover {
transform: scale(1.1);
}
}
.accept {
margin-left: 5px;
color: $green;
}
.refuse {
color: $red;
}
</style>