feat: flag management

This commit is contained in:
sam 2024-12-09 14:52:31 +01:00
parent 8bd4449804
commit d9d48c3cbf
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
24 changed files with 615 additions and 235 deletions

View file

@ -0,0 +1,37 @@
<script lang="ts">
import { Pagination, PaginationItem, PaginationLink } from "@sveltestrap/sveltestrap";
type Props = {
currentPage: number;
pageCount: number;
center?: boolean;
};
let { currentPage = $bindable(), pageCount, center }: Props = $props();
let prevPage = $derived(currentPage > 0 ? currentPage - 1 : 0);
let nextPage = $derived(currentPage < pageCount - 1 ? currentPage + 1 : pageCount - 1);
</script>
{#if pageCount > 1}
<div>
<Pagination listClassName={center ? "justify-content-center" : undefined}>
<PaginationItem>
<PaginationLink first onclick={() => (currentPage = 0)} />
</PaginationItem>
<PaginationItem>
<PaginationLink previous onclick={() => (currentPage = prevPage)} />
</PaginationItem>
{#each new Array(pageCount) as _, page}
<PaginationItem active={page === currentPage}>
<PaginationLink onclick={() => (currentPage = page)}>{page + 1}</PaginationLink>
</PaginationItem>
{/each}
<PaginationItem>
<PaginationLink next onclick={() => (currentPage = nextPage)} />
</PaginationItem>
<PaginationItem>
<PaginationLink last onclick={() => (currentPage = pageCount - 1)} />
</PaginationItem>
</Pagination>
</div>
{/if}

View file

@ -0,0 +1,17 @@
<script lang="ts">
import type { PrideFlag } from "$api/models/user";
import { DEFAULT_FLAG } from "$lib";
type Props = { flag: PrideFlag };
let { flag }: Props = $props();
</script>
<img class="flag" src={flag.image_url ?? DEFAULT_FLAG} alt={flag.description ?? flag.name} />
<style>
.flag {
height: 1.5rem;
max-width: 200px;
border-radius: 3px;
}
</style>

View file

@ -0,0 +1,52 @@
<script lang="ts">
import type { PrideFlag } from "$api/models";
import { DEFAULT_FLAG } from "$lib";
import { t } from "$lib/i18n";
type UpdateParams = { name: string; description: string | null };
type Props = {
flag: PrideFlag;
update(id: string, params: UpdateParams): Promise<void>;
deleteFlag(id: string): Promise<void>;
};
let { flag, update, deleteFlag }: Props = $props();
let name = $state(flag.name);
let description = $state(flag.description);
const saveChanges = () =>
update(flag.id, { name, description: description ? description : null });
</script>
<div class="d-flex">
<span class="me-3">
<img class="flag" src={flag.image_url ?? DEFAULT_FLAG} alt={flag.description ?? flag.name} />
</span>
<div class="w-lg-50">
<input class="mb-2 form-control" placeholder="Name" bind:value={name} autocomplete="off" />
<textarea
class="mb-2 form-control"
style="height: 5rem;"
placeholder="Description"
bind:value={description}
autocomplete="off"
></textarea>
<div class="btn-group">
<button type="button" class="btn btn-primary" onclick={saveChanges}>
{$t("save-changes")}
</button>
<button type="button" class="btn btn-outline-danger" onclick={() => deleteFlag(flag.id)}>
{$t("settings.flag-delete-button")}
</button>
</div>
</div>
</div>
<style>
.flag {
max-height: 6rem;
max-width: 256px;
border-radius: 3px;
}
</style>

View file

@ -1,5 +1,6 @@
<script lang="ts">
import type { PrideFlag } from "$api/models/user";
import { DEFAULT_FLAG } from "$lib";
import tippy from "$lib/tippy";
type Props = { flag: PrideFlag };
@ -10,7 +11,7 @@
<img
use:tippy={{ content: flag.description ?? flag.name }}
class="flag"
src={flag.image_url}
src={flag.image_url ?? DEFAULT_FLAG}
alt={flag.description ?? flag.name}
/>
{flag.name}