initial commit
Some checks failed
deploy / build-and-deploy (push) Failing after 21s

This commit is contained in:
2025-05-18 13:16:20 +02:00
commit 60f3f8a096
148 changed files with 17900 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
<script lang="ts">
import type { Feedback } from './types.ts';
import Input from '@components/input/Input.svelte';
import Textarea from '@components/input/Textarea.svelte';
// types
interface Props {
feedback: Feedback | null;
}
// inputs
let { feedback }: Props = $props();
</script>
<div
class="absolute bottom-2 bg-base-200 rounded-lg w-[calc(100%-1rem)] mx-2 flex px-6 py-4 gap-10"
hidden={feedback === null}
>
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2" onclick={() => (feedback = null)}>✕</button>
<div class="w-96">
<Input value={feedback?.event} label="Event" readonly />
<Input value={feedback?.title} label="Titel" readonly />
<Input value={feedback?.user?.username} label="Nutzer" readonly />
</div>
<div class="divider divider-horizontal"></div>
<div class="w-full">
<Textarea value={feedback?.content} label="Inhalt" rows={9} readonly dynamicWidth />
</div>
</div>

View File

@@ -0,0 +1,53 @@
<script lang="ts">
import BottomBar from './BottomBar.svelte';
import SortableTr from '@components/admin/table/SortableTr.svelte';
import SortableTh from '@components/admin/table/SortableTh.svelte';
import { feedbacks } from './state.ts';
import { fetchFeedbacks } from './actions.ts';
import { onMount } from 'svelte';
import type { Feedback } from './types.ts';
// consts
const dateFormat = new Intl.DateTimeFormat('de-DE', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
});
// states
let activeFeedback = $state<Feedback | null>(null);
// lifecycle
onMount(() => {
fetchFeedbacks();
});
</script>
<div class="min-h-[70vh] max-h-screen overflow-x-auto">
<table class="table table-pin-rows">
<thead>
<SortableTr data={feedbacks}>
<SortableTh style="width: 5%">#</SortableTh>
<SortableTh style="width: 10%">Event</SortableTh>
<SortableTh style="width: 20%" key="user.username">Nutzer</SortableTh>
<SortableTh style="width: 20%" key="lastChanged">Datum</SortableTh>
<SortableTh style="width: 45%">Inhalt</SortableTh>
</SortableTr>
</thead>
<tbody>
{#each $feedbacks as feedback, i (feedback.id)}
<tr class="hover:bg-base-200" onclick={() => (activeFeedback = feedback)}>
<td>{(i + 1)}</td>
<td>{feedback.event}</td>
<td>{feedback.user?.username}</td>
<td>{dateFormat.format(new Date(feedback.lastChanged))}</td>
<td>{feedback.content}</td>
</tr>
{/each}
</tbody>
</table>
</div>
<BottomBar feedback={activeFeedback} />

View File

@@ -0,0 +1,13 @@
import { actions } from 'astro:actions';
import { feedbacks } from './state.ts';
import { actionErrorPopup } from '@util/action.ts';
export async function fetchFeedbacks(reporter?: string | null, reported?: string | null) {
const { data, error } = await actions.feedback.feedbacks({ reporter: reporter, reported: reported });
if (error) {
actionErrorPopup(error);
return;
}
feedbacks.set(data.feedbacks);
}

View File

@@ -0,0 +1,4 @@
import { writable } from 'svelte/store';
import type { Feedbacks } from './types.ts';
export const feedbacks = writable<Feedbacks>([]);

View File

@@ -0,0 +1,4 @@
import type { ActionReturnType, actions } from 'astro:actions';
export type Feedbacks = Exclude<ActionReturnType<typeof actions.feedback.feedbacks>['data'], undefined>['feedbacks'];
export type Feedback = Feedbacks[0];