add admin settings
All checks were successful
delpoy / build-and-deploy (push) Successful in 40s

This commit is contained in:
2023-11-30 19:15:00 +01:00
parent 44454f445f
commit 235dfe3094
12 changed files with 176 additions and 9 deletions

View File

@ -16,6 +16,7 @@ export const load: LayoutServerLoad = async ({ route, cookies }) => {
? await Report.count({ where: { draft: false, status: ['none', 'review'] } })
: null,
adminCount: session?.permissions.adminRead() ? await Admin.count() : null,
settingsRead: session?.permissions.settingsRead(),
self: session
? JSON.parse(JSON.stringify(await Admin.findOne({ where: { id: session.userId } })))
: null

View File

@ -1,7 +1,7 @@
<script lang="ts">
import { page } from '$app/stores';
import { env } from '$env/dynamic/public';
import { ArrowLeftOnRectangle, Flag, UserGroup, Users } from 'svelte-heros-v2';
import { ArrowLeftOnRectangle, Cog6Tooth, Flag, UserGroup, Users } from 'svelte-heros-v2';
import { buttonTriggeredRequest } from '$lib/components/utils';
import { goto } from '$app/navigation';
import type { LayoutData } from './$types';
@ -44,6 +44,13 @@
name: 'Website Admins',
badge: $adminCount,
enabled: data.adminCount != null
},
{
path: `${env.PUBLIC_BASE_PATH}/admin/settings`,
icon: Cog6Tooth,
name: 'Website Einstellungen',
badge: null,
enabled: data.settingsRead
}
];
</script>
@ -57,7 +64,9 @@
<a href={tab.path}>
<svelte:component this={tab.icon} />
<span class="mr-1" class:underline={$page.url.pathname === tab.path}>{tab.name}</span>
<div class="badge">{tab.badge}</div>
{#if tab.badge != null}
<div class="badge">{tab.badge}</div>
{/if}
</a>
</li>
{/if}
@ -74,7 +83,7 @@
</ul>
</div>
</div>
<div class="h-full w-full overflow-y-scroll overflow-x-hidden">
<div class="h-full w-full -mt-12 pt-12 overflow-y-scroll overflow-x-hidden">
<slot />
</div>
{:else}

View File

@ -1,7 +1,7 @@
<script lang="ts">
import type { PageData } from './$types';
import { env } from '$env/dynamic/public';
import { Flag, UserGroup, Users } from 'svelte-heros-v2';
import { Cog6Tooth, Flag, UserGroup, Users } from 'svelte-heros-v2';
export let data: PageData;
@ -23,6 +23,12 @@
icon: Users,
name: 'Website Admins',
enabled: data.adminCount != null
},
{
path: `${env.PUBLIC_BASE_PATH}/admin/settings`,
icon: Cog6Tooth,
name: 'Website Einstellungen',
enabled: data.settingsRead
}
];
</script>

View File

@ -16,7 +16,9 @@
'User Read': Permissions.UserRead,
'User Write': Permissions.UserWrite,
'Report Read': Permissions.ReportRead,
'Report Write': Permissions.ReportWrite
'Report Write': Permissions.ReportWrite,
'Settings Read': Permissions.SettingsRead,
'Settings Write': Permissions.SettingsWrite
};
let newAdminUsername: string;

View File

@ -0,0 +1,30 @@
import type { PageServerLoad } from './$types';
import { getSession } from '$lib/server/session';
import { Permissions } from '$lib/permissions';
import { redirect } from '@sveltejs/kit';
import { env } from '$env/dynamic/public';
import { Settings } from '$lib/server/database';
export const load: PageServerLoad = async ({ parent, cookies }) => {
if (getSession(cookies, { permissions: [Permissions.SettingsRead] }) == null) {
throw redirect(302, `${env.PUBLIC_BASE_PATH}/admin`);
}
const { self } = await parent();
const settings = (await Settings.findAll()).reduce(
(prev, curr) => {
return { ...prev, [curr.key]: curr.value };
},
{} as { [key: string]: any }
);
return {
settings: {
register: {
enabled: settings['register.enabled'] ?? true
}
},
self: self
};
};

View File

@ -0,0 +1,42 @@
<script lang="ts">
import type { PageData } from './$types';
import { env } from '$env/dynamic/public';
export let data: PageData;
let settings = structuredClone(data.settings);
async function change() {
await fetch(`${env.PUBLIC_BASE_PATH}/admin/settings`, {
method: 'POST',
body: JSON.stringify({
register: {
enabled: returnIfNoDup(settings.register.enabled, data.settings.register.enabled)
}
} as PageData['settings'])
});
data.settings = settings;
settings = structuredClone(data.settings);
}
function returnIfNoDup<T>(value: T, original: T): T | undefined {
return value != original ? value : undefined;
}
</script>
<div class="h-full flex flex-col items-center justify-between">
<div class="grid grid-cols-3 w-full [&>*]:mx-8">
<div>
<div class="divider">Anmeldung</div>
<label class="label cursor-pointer">
<span class="label-text">Aktiviert</span>
<input type="checkbox" class="toggle" bind:checked={settings.register.enabled} />
</label>
</div>
</div>
<div class="mb-6">
<button
class="btn btn-success mt-auto"
class:btn-disabled={JSON.stringify(data.settings) === JSON.stringify(settings)}
on:click={change}>Speichern</button
>
</div>
</div>

View File

@ -0,0 +1,30 @@
import type { PageData } from './$types';
import type { RequestHandler } from '@sveltejs/kit';
import { getSession } from '$lib/server/session';
import { Permissions } from '$lib/permissions';
import { Settings } from '$lib/server/database';
export const POST = (async ({ request, cookies }) => {
if (getSession(cookies, { permissions: [Permissions.SettingsWrite] }) == null) {
return new Response(null, {
status: 401
});
}
const settings: PageData['settings'] = await request.json();
for (const [key, value] of Object.entries(settings.register)) {
const setting = await Settings.findOne({ where: { key: `register.${key}` } });
if (setting) {
setting.value = JSON.stringify(value);
await setting.save();
} else {
await Settings.create({
key: `register.${key}`,
value: JSON.stringify(value)
});
}
}
return new Response();
}) satisfies RequestHandler;