fuck that shit, revert
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				delpoy / build-and-deploy (push) Successful in 1m3s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	delpoy / build-and-deploy (push) Successful in 1m3s
				
			This commit is contained in:
		| @@ -6,21 +6,6 @@ | ||||
| 	let bodyElem: HTMLTableSectionElement; | ||||
| 	let intersectionElem: HTMLElement; | ||||
|  | ||||
| 	async function onUpdateProxy() { | ||||
| 		let scrollElem: HTMLElement | null = bodyElem; | ||||
| 		while (scrollElem && scrollElem.scrollHeight <= scrollElem.clientHeight) { | ||||
| 			scrollElem = scrollElem.parentElement; | ||||
| 		} | ||||
|  | ||||
| 		const scrollTop = scrollElem?.scrollTop ?? 0; | ||||
|  | ||||
| 		await onUpdate(); | ||||
|  | ||||
| 		if (scrollElem) scrollElem.scrollTop = scrollTop; | ||||
|  | ||||
| 		await tick(); | ||||
| 	} | ||||
|  | ||||
| 	async function getIntersectionElement(): Promise<HTMLElement> { | ||||
| 		if (!bodyElem.lastElementChild) { | ||||
| 			await new Promise<void>((resolve) => { | ||||
| @@ -36,7 +21,8 @@ | ||||
| 	} | ||||
|  | ||||
| 	onMount(async () => { | ||||
| 		await onUpdateProxy(); | ||||
| 		await onUpdate(); | ||||
| 		await tick(); | ||||
|  | ||||
| 		if (!bodyElem) return; | ||||
|  | ||||
| @@ -47,7 +33,8 @@ | ||||
|  | ||||
| 				const rows = bodyElem.rows.length; | ||||
|  | ||||
| 				await onUpdateProxy(); | ||||
| 				await onUpdate(); | ||||
| 				await tick(); | ||||
|  | ||||
| 				if (rows === bodyElem.rows.length) return; | ||||
| 				observer.observe((intersectionElem = await getIntersectionElement())); | ||||
|   | ||||
| @@ -82,7 +82,7 @@ | ||||
|  | ||||
| 	let pageTitleSuffix = $derived( | ||||
| 		tabs.find((t) => $page.url.pathname === t.path)?.name ?? | ||||
| 			($page.url.pathname === `${env.PUBLIC_BASE_PATH}/admin/login` ? 'Login' : null) | ||||
| 		($page.url.pathname === `${env.PUBLIC_BASE_PATH}/admin/login` ? 'Login' : null) | ||||
| 	); | ||||
| </script> | ||||
|  | ||||
| @@ -133,7 +133,7 @@ | ||||
| 	<div class="grid"> | ||||
| 		{#key $page.url.pathname} | ||||
| 			<div | ||||
| 				class="col-[1] row-[1] h-[calc(100vh-3rem)] w-full overflow-y-scroll overflow-x-hidden" | ||||
| 				class="col-[1] row-[1] h-full w-full overflow-y-scroll overflow-x-hidden" | ||||
| 				in:fly={{ x: transitionPrefix * window.innerWidth, duration: !transitionPrefix ? 0 : 100 }} | ||||
| 				out:fly={{ | ||||
| 					x: transitionPrefix * -window.innerWidth, | ||||
| @@ -145,7 +145,7 @@ | ||||
| 		{/key} | ||||
| 	</div> | ||||
| {:else} | ||||
| 	<div class="h-[calc(100vh-3rem)] w-full"> | ||||
| 	<div class="h-full w-full"> | ||||
| 		{@render children()} | ||||
| 	</div> | ||||
| {/if} | ||||
|   | ||||
| @@ -66,67 +66,65 @@ | ||||
| 			onUpdate={() => fetchFeedback({ from: 0 }).then((r) => (feedbacks = r))} | ||||
| 		/> | ||||
| 		<hr class="divider my-1 mx-8 border-none" /> | ||||
| 		<div class="h-full overflow-scroll"> | ||||
| 			<table class="table table-fixed h-fit"> | ||||
| 				<thead> | ||||
| 					<tr> | ||||
| 						<th>Event</th> | ||||
| 						<th>Titel</th> | ||||
| 						<th>Nutzer</th> | ||||
| 						<th>Datum</th> | ||||
| 						<th>Inhalt</th> | ||||
| 					</tr> | ||||
| 				</thead> | ||||
| 				<PaginationTableBody | ||||
| 					onUpdate={async () => | ||||
| 						await fetchFeedback().then((feedback) => (feedbacks = [...feedbacks, ...feedback]))} | ||||
| 				> | ||||
| 					{#each feedbacks as feedback} | ||||
| 						<tr | ||||
| 							class="hover [&>*]:text-sm cursor-pointer" | ||||
| 							class:bg-base-200={activeFeedback?.url_hash === feedback.url_hash} | ||||
| 							onclick={async () => { | ||||
| 								await goto(`${window.location.href.split('#')[0]}#${feedback.url_hash}`, { | ||||
| 									replaceState: true | ||||
| 								}); | ||||
| 								await openHashReport(); | ||||
| 							}} | ||||
| 		<table class="table table-fixed h-fit"> | ||||
| 			<thead> | ||||
| 			<tr> | ||||
| 				<th>Event</th> | ||||
| 				<th>Titel</th> | ||||
| 				<th>Nutzer</th> | ||||
| 				<th>Datum</th> | ||||
| 				<th>Inhalt</th> | ||||
| 			</tr> | ||||
| 			</thead> | ||||
| 			<PaginationTableBody | ||||
| 				onUpdate={async () => | ||||
| 					await fetchFeedback().then((feedback) => (feedbacks = [...feedbacks, ...feedback]))} | ||||
| 			> | ||||
| 				{#each feedbacks as feedback} | ||||
| 					<tr | ||||
| 						class="hover [&>*]:text-sm cursor-pointer" | ||||
| 						class:bg-base-200={activeFeedback?.url_hash === feedback.url_hash} | ||||
| 						onclick={async () => { | ||||
| 							await goto(`${window.location.href.split('#')[0]}#${feedback.url_hash}`, { | ||||
| 								replaceState: true | ||||
| 							}); | ||||
| 							await openHashReport(); | ||||
| 						}} | ||||
| 					> | ||||
| 						<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} | ||||
| 								<button | ||||
| 									class="pl-1" | ||||
| 									title="Nach Ersteller filtern" | ||||
| 									onclick={(e) => { | ||||
| 										e.stopPropagation(); | ||||
| 										feedbackFilter.username = feedback.user.username; | ||||
| 										fetchFeedback({ from: 0 }).then((r) => (feedbacks = r)); | ||||
| 									}} | ||||
| 								> | ||||
| 									<MagnifyingGlass size="14" /> | ||||
| 								</button> | ||||
| 							{/if} | ||||
| 						</td> | ||||
| 						<td | ||||
| 						>{new Intl.DateTimeFormat('de-DE', { | ||||
| 							year: 'numeric', | ||||
| 							month: '2-digit', | ||||
| 							day: '2-digit', | ||||
| 							hour: '2-digit', | ||||
| 							minute: '2-digit' | ||||
| 						}).format(new Date(feedback.updatedAt))} Uhr</td | ||||
| 						> | ||||
| 							<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} | ||||
| 									<button | ||||
| 										class="pl-1" | ||||
| 										title="Nach Ersteller filtern" | ||||
| 										onclick={(e) => { | ||||
| 											e.stopPropagation(); | ||||
| 											feedbackFilter.username = feedback.user.username; | ||||
| 											fetchFeedback({ from: 0 }).then((r) => (feedbacks = r)); | ||||
| 										}} | ||||
| 									> | ||||
| 										<MagnifyingGlass size="14" /> | ||||
| 									</button> | ||||
| 								{/if} | ||||
| 							</td> | ||||
| 							<td | ||||
| 								>{new Intl.DateTimeFormat('de-DE', { | ||||
| 									year: 'numeric', | ||||
| 									month: '2-digit', | ||||
| 									day: '2-digit', | ||||
| 									hour: '2-digit', | ||||
| 									minute: '2-digit' | ||||
| 								}).format(new Date(feedback.updatedAt))} Uhr</td | ||||
| 							> | ||||
| 							<td class="overflow-hidden overflow-ellipsis" | ||||
| 								>{feedback.content}{feedback.content_stripped ? '...' : ''}</td | ||||
| 							> | ||||
| 						</tr> | ||||
| 					{/each} | ||||
| 				</PaginationTableBody> | ||||
| 			</table> | ||||
| 		</div> | ||||
| 						<td class="overflow-hidden overflow-ellipsis" | ||||
| 						>{feedback.content}{feedback.content_stripped ? '...' : ''}</td | ||||
| 						> | ||||
| 					</tr> | ||||
| 				{/each} | ||||
| 			</PaginationTableBody> | ||||
| 		</table> | ||||
| 	</div> | ||||
| 	{#if activeFeedback} | ||||
| 		<div | ||||
|   | ||||
| @@ -115,97 +115,95 @@ | ||||
| 			</div> | ||||
| 		</div> | ||||
| 		<hr class="divider my-1 mx-8 border-none" /> | ||||
| 		<div class="h-full overflow-scroll"> | ||||
| 			<table class="table table-fixed h-fit"> | ||||
| 				<colgroup> | ||||
| 					<col style="width: 20%" /> | ||||
| 					<col style="width: 15%" /> | ||||
| 					<col style="width: 15%" /> | ||||
| 					<col style="width: 20%" /> | ||||
| 					<col style="width: 15%" /> | ||||
| 					<col style="width: 15%" /> | ||||
| 				</colgroup> | ||||
| 				<thead> | ||||
| 					<tr> | ||||
| 						<th>Grund</th> | ||||
| 						<th>Ersteller</th> | ||||
| 						<th>Reporteter User</th> | ||||
| 						<th>Datum</th> | ||||
| 						<th>Bearbeitungsstatus</th> | ||||
| 						<th>Reportstatus</th> | ||||
| 					</tr> | ||||
| 				</thead> | ||||
| 				<PaginationTableBody | ||||
| 					onUpdate={async () => | ||||
| 						await fetchReports().then((res) => (reports = [...reports, ...res.reports]))} | ||||
| 				> | ||||
| 					{#each reports as report} | ||||
| 						<tr | ||||
| 							class="hover [&>*]:text-sm cursor-pointer" | ||||
| 							class:bg-base-200={activeReport?.url_hash === report.url_hash} | ||||
| 							onclick={() => { | ||||
| 								goto(`${window.location.href.split('#')[0]}#${report.url_hash}`, { | ||||
| 									replaceState: true | ||||
| 								}); | ||||
| 								activeReport = $state.snapshot(report); | ||||
| 								activeReport.originalStatus = report.status; | ||||
| 							}} | ||||
| 						> | ||||
| 							<td title={report.subject}><div class="overflow-scroll">{report.subject}</div></td> | ||||
| 							<td class="flex"> | ||||
| 								{report.reporter.username} | ||||
| 		<table class="table table-fixed h-fit"> | ||||
| 			<colgroup> | ||||
| 				<col style="width: 20%" /> | ||||
| 				<col style="width: 15%" /> | ||||
| 				<col style="width: 15%" /> | ||||
| 				<col style="width: 20%" /> | ||||
| 				<col style="width: 15%" /> | ||||
| 				<col style="width: 15%" /> | ||||
| 			</colgroup> | ||||
| 			<thead> | ||||
| 			<tr> | ||||
| 				<th>Grund</th> | ||||
| 				<th>Ersteller</th> | ||||
| 				<th>Reporteter User</th> | ||||
| 				<th>Datum</th> | ||||
| 				<th>Bearbeitungsstatus</th> | ||||
| 				<th>Reportstatus</th> | ||||
| 			</tr> | ||||
| 			</thead> | ||||
| 			<PaginationTableBody | ||||
| 				onUpdate={async () => | ||||
| 					await fetchReports().then((res) => (reports = [...reports, ...res.reports]))} | ||||
| 			> | ||||
| 				{#each reports as report} | ||||
| 					<tr | ||||
| 						class="hover [&>*]:text-sm cursor-pointer" | ||||
| 						class:bg-base-200={activeReport?.url_hash === report.url_hash} | ||||
| 						onclick={() => { | ||||
| 							goto(`${window.location.href.split('#')[0]}#${report.url_hash}`, { | ||||
| 								replaceState: true | ||||
| 							}); | ||||
| 							activeReport = $state.snapshot(report); | ||||
| 							activeReport.originalStatus = report.status; | ||||
| 						}} | ||||
| 					> | ||||
| 						<td title={report.subject}><div class="overflow-scroll">{report.subject}</div></td> | ||||
| 						<td class="flex"> | ||||
| 							{report.reporter.username} | ||||
| 							<button | ||||
| 								class="pl-1" | ||||
| 								title="Nach Ersteller filtern" | ||||
| 								onclick={(e) => { | ||||
| 									e.stopPropagation(); | ||||
| 									reportFilter.reporter = report.reporter.username; | ||||
| 									fetchReports({ from: 0 }).then((r) => (reports = r.reports)); | ||||
| 								}} | ||||
| 							> | ||||
| 								<MagnifyingGlass size="14" /> | ||||
| 							</button> | ||||
| 						</td> | ||||
| 						<td> | ||||
| 							{report.reported?.username || ''} | ||||
| 							{#if report.reported?.id} | ||||
| 								<button | ||||
| 									class="pl-1" | ||||
| 									title="Nach Ersteller filtern" | ||||
| 									title="Nach Reportetem Spieler filtern" | ||||
| 									onclick={(e) => { | ||||
| 										e.stopPropagation(); | ||||
| 										reportFilter.reporter = report.reporter.username; | ||||
| 										reportFilter.reported = report.reported.username; | ||||
| 										fetchReports({ from: 0 }).then((r) => (reports = r.reports)); | ||||
| 									}} | ||||
| 								> | ||||
| 									<MagnifyingGlass size="14" /> | ||||
| 								</button> | ||||
| 							</td> | ||||
| 							<td> | ||||
| 								{report.reported?.username || ''} | ||||
| 								{#if report.reported?.id} | ||||
| 									<button | ||||
| 										class="pl-1" | ||||
| 										title="Nach Reportetem Spieler filtern" | ||||
| 										onclick={(e) => { | ||||
| 											e.stopPropagation(); | ||||
| 											reportFilter.reported = report.reported.username; | ||||
| 											fetchReports({ from: 0 }).then((r) => (reports = r.reports)); | ||||
| 										}} | ||||
| 									> | ||||
| 										<MagnifyingGlass size="14" /> | ||||
| 									</button> | ||||
| 								{/if} | ||||
| 							</td> | ||||
| 							<td | ||||
| 								>{new Intl.DateTimeFormat('de-DE', { | ||||
| 									year: 'numeric', | ||||
| 									month: '2-digit', | ||||
| 									day: '2-digit', | ||||
| 									hour: '2-digit', | ||||
| 									minute: '2-digit' | ||||
| 								}).format(new Date(report.createdAt))} Uhr</td | ||||
| 							> | ||||
| 							<td> | ||||
| 								{report.status === 'none' | ||||
| 									? 'Unbearbeitet' | ||||
| 									: report.status === 'review' | ||||
| 										? 'In Bearbeitung' | ||||
| 										: report.status === 'reviewed' | ||||
| 											? 'Bearbeitet' | ||||
| 											: ''} | ||||
| 							</td> | ||||
| 							<td>{report.draft ? 'Entwurf' : 'Erstellt'}</td> | ||||
| 						</tr> | ||||
| 					{/each} | ||||
| 				</PaginationTableBody> | ||||
| 			</table> | ||||
| 		</div> | ||||
| 							{/if} | ||||
| 						</td> | ||||
| 						<td | ||||
| 						>{new Intl.DateTimeFormat('de-DE', { | ||||
| 							year: 'numeric', | ||||
| 							month: '2-digit', | ||||
| 							day: '2-digit', | ||||
| 							hour: '2-digit', | ||||
| 							minute: '2-digit' | ||||
| 						}).format(new Date(report.createdAt))} Uhr</td | ||||
| 						> | ||||
| 						<td> | ||||
| 							{report.status === 'none' | ||||
| 								? 'Unbearbeitet' | ||||
| 								: report.status === 'review' | ||||
| 									? 'In Bearbeitung' | ||||
| 									: report.status === 'reviewed' | ||||
| 										? 'Bearbeitet' | ||||
| 										: ''} | ||||
| 						</td> | ||||
| 						<td>{report.draft ? 'Entwurf' : 'Erstellt'}</td> | ||||
| 					</tr> | ||||
| 				{/each} | ||||
| 			</PaginationTableBody> | ||||
| 		</table> | ||||
| 	</div> | ||||
| 	{#if activeReport} | ||||
| 		<div | ||||
| @@ -307,7 +305,7 @@ | ||||
| 					<option | ||||
| 						value="none" | ||||
| 						disabled={activeReport.auditor != null || activeReport.notice || activeReport.statement} | ||||
| 						>Unbearbeitet</option | ||||
| 					>Unbearbeitet</option | ||||
| 					> | ||||
| 					<option value="review">In Bearbeitung</option> | ||||
| 					<option value="reviewed">Bearbeitet</option> | ||||
|   | ||||
| @@ -95,19 +95,19 @@ | ||||
| 	<div class="h-full overflow-scroll" bind:this={userTableContainerElement}> | ||||
| 		<table class="table table-auto"> | ||||
| 			<thead> | ||||
| 				<!-- prettier-ignore --> | ||||
| 				<SortableTr> | ||||
| 					<th></th> | ||||
| 					<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'firstname', asc: e.asc}}}>Vorname</SortableTh> | ||||
| 					<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'lastname', asc: e.asc}}}>Nachname</SortableTh> | ||||
| 					<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'birthday', asc: e.asc}}}>Geburtstag</SortableTh> | ||||
| 					<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'telephone', asc: e.asc}}}>Telefon</SortableTh> | ||||
| 					<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'username', asc: e.asc}}}>Username</SortableTh> | ||||
| 					<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'playertype', asc: e.asc}}}>Minecraft Edition</SortableTh> | ||||
| 					<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'password', asc: e.asc}}}>Passwort</SortableTh> | ||||
| 					<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'uuid', asc: e.asc}}}>UUID</SortableTh> | ||||
| 					<th></th> | ||||
| 				</SortableTr> | ||||
| 			<!-- prettier-ignore --> | ||||
| 			<SortableTr class="[&>th]:bg-base-100 [&>th]:z-[1] [&>th]:sticky [&>th]:top-0"> | ||||
| 				<th></th> | ||||
| 				<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'firstname', asc: e.asc}}}>Vorname</SortableTh> | ||||
| 				<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'lastname', asc: e.asc}}}>Nachname</SortableTh> | ||||
| 				<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'birthday', asc: e.asc}}}>Geburtstag</SortableTh> | ||||
| 				<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'telephone', asc: e.asc}}}>Telefon</SortableTh> | ||||
| 				<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'username', asc: e.asc}}}>Username</SortableTh> | ||||
| 				<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'playertype', asc: e.asc}}}>Minecraft Edition</SortableTh> | ||||
| 				<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'password', asc: e.asc}}}>Passwort</SortableTh> | ||||
| 				<SortableTh onSort={(e) => userFilter = {...userFilter, sort: {key: 'uuid', asc: e.asc}}}>UUID</SortableTh> | ||||
| 				<th></th> | ||||
| 			</SortableTr> | ||||
| 			</thead> | ||||
| 			<PaginationTableBody | ||||
| 				onUpdate={async () => { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user