diff --git a/src/lib/server/database.ts b/src/lib/server/database.ts index fa5cd4a..6513c0a 100644 --- a/src/lib/server/database.ts +++ b/src/lib/server/database.ts @@ -113,6 +113,8 @@ export class Feedback extends Model { @Column({ type: DataTypes.STRING, allowNull: false }) declare event: string; @Column({ type: DataTypes.STRING }) + declare title: string | null; + @Column({ type: DataTypes.STRING }) declare content: string | null; @Column({ type: DataTypes.STRING, allowNull: false, unique: true }) @Index diff --git a/src/routes/admin/feedback/+page.svelte b/src/routes/admin/feedback/+page.svelte index 9b5c38a..bd733b1 100644 --- a/src/routes/admin/feedback/+page.svelte +++ b/src/routes/admin/feedback/+page.svelte @@ -70,6 +70,7 @@ <thead> <tr> <th>Event</th> + <th>Titel</th> <th>Nutzer</th> <th>Datum</th> <th>Inhalt</th> @@ -91,6 +92,7 @@ }} > <td title={feedback.event}>{feedback.event}</td> + <td class="overflow-hidden overflow-ellipsis">{feedback.title}</td> <td class="flex"> {feedback.user?.username || ''} {#if feedback.user} @@ -116,7 +118,9 @@ minute: '2-digit' }).format(new Date(feedback.updatedAt))} Uhr</td > - <td>{feedback.content}...</td> + <td class="overflow-hidden overflow-ellipsis" + >{feedback.content}{feedback.content_stripped ? '...' : ''}</td + > </tr> {/each} </PaginationTableBody> @@ -167,6 +171,18 @@ </div> <h3 class="font-roboto font-semibold text-2xl mb-2">Feedback</h3> <div class="w-full"> + <Input readonly={true} size="sm" value={activeFeedback.event} pickyWidth={false}> + {#snippet label()} + <span>Event</span> + {/snippet} + </Input> + <Input readonly={true} size="sm" value={activeFeedback.title} pickyWidth={false}> + {#snippet label()} + <span>Titel</span> + {/snippet} + </Input> + <Textarea readonly={true} rows={4} label="Inhalt" value={activeFeedback.content} /> + <div class="divider mb-1"></div> <Input readonly={true} size="sm" @@ -177,7 +193,6 @@ <span>Nutzer</span> {/snippet} </Input> - <Textarea readonly={true} rows={4} label="Inhalt" value={activeFeedback.content} /> </div> </div> {/if} diff --git a/src/routes/admin/feedback/+server.ts b/src/routes/admin/feedback/+server.ts index dffd56a..17916b6 100644 --- a/src/routes/admin/feedback/+server.ts +++ b/src/routes/admin/feedback/+server.ts @@ -42,7 +42,10 @@ export const POST = (async ({ request, cookies }) => { attributes: data.preview ? { exclude: ['content'], - include: [[sequelize.literal('SUBSTR(content, 1, 50)'), 'content']] + include: [ + [sequelize.literal('SUBSTR(content, 1, 50)'), 'content'], + [sequelize.literal('LENGTH(content) > 50'), 'content_stripped'] + ] } : undefined, include: { model: User, as: 'user' }, diff --git a/src/routes/api/feedback/+server.ts b/src/routes/api/feedback/+server.ts index b6875b4..2a62c7e 100644 --- a/src/routes/api/feedback/+server.ts +++ b/src/routes/api/feedback/+server.ts @@ -21,9 +21,10 @@ export const POST = (async ({ request, url }) => { where: { uuid: data.users }, attributes: ['id', 'uuid'] })) { - feedback[user.uuid] = { + feedback[user.uuid!] = { url_hash: crypto.randomBytes(18).toString('hex'), event: data.event, + title: data.title ?? null, draft: true, user_id: user.id }; diff --git a/src/routes/api/feedback/schema.ts b/src/routes/api/feedback/schema.ts index 381e7bb..8c980c4 100644 --- a/src/routes/api/feedback/schema.ts +++ b/src/routes/api/feedback/schema.ts @@ -2,5 +2,6 @@ import { z } from 'zod'; export const FeedbackAddSchema = z.object({ event: z.string(), + title: z.string().nullish(), users: z.array(z.string()) }); diff --git a/src/routes/feedback/[...url_hash]/+page.server.ts b/src/routes/feedback/[...url_hash]/+page.server.ts index 4e424a7..d247bf3 100644 --- a/src/routes/feedback/[...url_hash]/+page.server.ts +++ b/src/routes/feedback/[...url_hash]/+page.server.ts @@ -12,7 +12,7 @@ export const load: PageServerLoad = async ({ params }) => { return { draft: feedback.content === null, - event: feedback.event, + title: feedback.title, anonymous: feedback.user_id === null }; }; diff --git a/src/routes/feedback/[...url_hash]/+page.svelte b/src/routes/feedback/[...url_hash]/+page.svelte index 4153d6c..dea1669 100644 --- a/src/routes/feedback/[...url_hash]/+page.svelte +++ b/src/routes/feedback/[...url_hash]/+page.svelte @@ -16,7 +16,7 @@ {#if draft} <div class="col-[1] row-[1]" transition:fly={{ x: -200, duration: 300 }}> - <FeedbackDraft event={data.event} anonymous={data.anonymous} onSubmit={() => (draft = false)} /> + <FeedbackDraft title={data.title} anonymous={data.anonymous} onSubmit={() => (draft = false)} /> </div> {:else} <div class="col-[1] row-[1]" transition:fly={{ x: 200, duration: 300 }}> diff --git a/src/routes/feedback/[...url_hash]/FeedbackDraft.svelte b/src/routes/feedback/[...url_hash]/FeedbackDraft.svelte index 5f0e854..21047ef 100644 --- a/src/routes/feedback/[...url_hash]/FeedbackDraft.svelte +++ b/src/routes/feedback/[...url_hash]/FeedbackDraft.svelte @@ -5,8 +5,11 @@ import { page } from '$app/stores'; import { getPopupModalShowFn } from '$lib/context'; - let { event, anonymous, onSubmit }: { event: string; anonymous: boolean; onSubmit?: () => void } = - $props(); + let { + title, + anonymous, + onSubmit + }: { title: string | null; anonymous: boolean; onSubmit?: () => void } = $props(); let showPopupModal = getPopupModalShowFn(); @@ -47,11 +50,13 @@ }} > <div class="space-y-4 my-4"> - <Input size="sm" pickyWidth={false} disabled value={event}> - {#snippet label()} - <span>Event</span> - {/snippet} - </Input> + {#if title} + <Input size="sm" pickyWidth={false} disabled value={title}> + {#snippet label()} + <span>Event</span> + {/snippet} + </Input> + {/if} <Textarea required={true} rows={4} label="Feedback" bind:value={content} /> {#if !anonymous} <div class="flex items-center gap-2 mt-2">