implemented permission system

This commit is contained in:
Alex
2025-03-02 10:27:56 +01:00
parent 298ef9843e
commit 29f405385e
6 changed files with 311 additions and 167 deletions

View File

@@ -5,6 +5,8 @@
import { page } from '$app/stores';
import { t } from 'svelte-i18n';
import { writable } from 'svelte/store';
import { PERMISSIONS } from '$lib/utils/constants';
import { hasPrivilige } from '$lib/utils/helpers';
let isMobileMenuOpen = false;
@@ -104,7 +106,7 @@
{$page.data.user.last_name}
</a>
</div>
{#if $page.data.user.role_id > 0}
{#if hasPrivilige($page.data.user, PERMISSIONS.View)}
<div
class="header-nav-item"
class:active={$page.url.pathname.startsWith(`${base}/auth/admin/users`)}

View File

@@ -3,8 +3,9 @@
import SmallLoader from '$lib/components/SmallLoader.svelte';
import { createEventDispatcher } from 'svelte';
import { applyAction, enhance } from '$app/forms';
import { receive, send } from '$lib/utils/helpers';
import { hasPrivilige, receive, send } from '$lib/utils/helpers';
import { t } from 'svelte-i18n';
import { PERMISSIONS } from '$lib/utils/constants';
/** @type {import('../../routes/auth/about/[id]/$types').ActionData} */
export let form;
@@ -29,7 +30,7 @@
profile_picture: '',
payment_status: 0,
status: 1,
role_id: 0,
role_id: 1,
membership: {
id: 0,
start_date: '',
@@ -70,12 +71,14 @@
/** @type {App.Locals['user'] | null} */
export let user;
/** @type {Number} */
export let role_id;
/** @type {App.Locals['user']} */
export let editor;
/** @type {App.Locals['user'] } */
let localUser;
let readonlyUser = !hasPrivilige(editor, PERMISSIONS.Update);
$: {
if (user !== undefined && !localUser) {
localUser =
@@ -106,8 +109,9 @@
const userRoleOptions = [
{ value: 0, label: $t('userRole.0'), color: '--subtext1' }, // Grey for "Nicht verifiziert"
{ value: 1, label: $t('userRole.1'), color: '--light-green' }, // Light green for "Verifiziert"
{ value: 4, label: $t('userRole.4'), color: '--green' }, // Green for "Aktiv"
{ value: 8, label: $t('userRole.8'), color: '--pink' } // Pink for "Passiv"
{ value: 2, label: $t('userRole.2'), color: '--green' }, // Light green for "Verifiziert"
{ value: 4, label: $t('userRole.4'), color: '--pink' }, // Green for "Aktiv"
{ value: 8, label: $t('userRole.8'), color: '--red' } // Pink for "Passiv"
];
const membershipStatusOptions = [
{ value: 3, label: $t('userStatus.3'), color: '--green' }, // Green for "Aktiv"
@@ -232,9 +236,9 @@
label={$t('status')}
bind:value={localUser.status}
options={userStatusOptions}
readonly={role_id === 0}
readonly={readonlyUser}
/>
{#if role_id === 8}
{#if hasPrivilige(editor, PERMISSIONS.Super)}
<InputField
name="user[role_id]"
type="select"
@@ -243,29 +247,31 @@
options={userRoleOptions}
/>
{/if}
<InputField
name="user[password]"
type="password"
label={$t('password')}
placeholder={$t('placeholder.password')}
bind:value={password}
otherPasswordValue={confirm_password}
/>
<InputField
name="confirm_password"
type="password"
label={$t('confirm_password')}
placeholder={$t('placeholder.password')}
bind:value={confirm_password}
otherPasswordValue={password}
/>
{#if hasPrivilige(localUser, PERMISSIONS.Member)}
<InputField
name="user[password]"
type="password"
label={$t('password')}
placeholder={$t('placeholder.password')}
bind:value={password}
otherPasswordValue={confirm_password}
/>
<InputField
name="confirm_password"
type="password"
label={$t('confirm_password')}
placeholder={$t('placeholder.password')}
bind:value={confirm_password}
otherPasswordValue={password}
/>
{/if}
<InputField
name="user[first_name]"
label={$t('user.first_name')}
bind:value={localUser.first_name}
placeholder={$t('placeholder.first_name')}
required={true}
readonly={role_id === 0}
readonly={readonlyUser}
/>
<InputField
name="user[last_name]"
@@ -273,7 +279,7 @@
bind:value={localUser.last_name}
placeholder={$t('placeholder.last_name')}
required={true}
readonly={role_id === 0}
readonly={readonlyUser}
/>
<InputField
name="user[company]"
@@ -296,14 +302,16 @@
bind:value={localUser.phone}
placeholder={$t('placeholder.phone')}
/>
<InputField
name="user[dateofbirth]"
type="date"
label={$t('user.dateofbirth')}
bind:value={localUser.dateofbirth}
placeholder={$t('placeholder.dateofbirth')}
readonly={role_id === 0}
/>
{#if hasPrivilige(localUser, PERMISSIONS.Member)}
<InputField
name="user[dateofbirth]"
type="date"
label={$t('user.dateofbirth')}
bind:value={localUser.dateofbirth}
placeholder={$t('placeholder.dateofbirth')}
readonly={readonlyUser}
/>
{/if}
<InputField
name="user[address]"
label={$t('address')}
@@ -322,7 +330,7 @@
bind:value={localUser.city}
placeholder={$t('placeholder.city')}
/>
{#if role_id > 0}
{#if !readonlyUser}
<InputField
name="user[notes]"
type="textarea"
@@ -335,77 +343,80 @@
/>
{/if}
</div>
<div class="tab-content" style="display: {activeTab === 'licence' ? 'block' : 'none'}">
<InputField
name="user[licence][status]"
type="select"
label={$t('status')}
bind:value={localUser.licence.status}
options={licenceStatusOptions}
readonly={role_id === 0}
/>
<InputField
name="user[licence][number]"
type="text"
label={$t('licence_number')}
bind:value={localUser.licence.number}
placeholder={$t('placeholder.licence_number')}
toUpperCase={true}
readonly={role_id === 0}
/>
<InputField
name="user[licence][issued_date]"
type="date"
label={$t('issued_date')}
bind:value={localUser.licence.issued_date}
placeholder={$t('placeholder.issued_date')}
readonly={role_id === 0}
/>
<InputField
name="user[licence][expiration_date]"
type="date"
label={$t('expiration_date')}
bind:value={localUser.licence.expiration_date}
placeholder={$t('placeholder.expiration_date')}
readonly={role_id === 0}
/>
<InputField
name="user[licence][country]"
label={$t('country')}
bind:value={localUser.licence.country}
placeholder={$t('placeholder.issuing_country')}
readonly={role_id === 0}
/>
<div class="licence-categories">
<h3>{$t('licence_categories')}</h3>
<div class="checkbox-grid">
{#each Object.entries(groupedCategories) as [, categories], groupIndex}
{#if groupIndex > 0}
<div class="category-break"></div>
{/if}
{#each categories as category}
<div class="checkbox-item">
<div class="checkbox-label-container">
<InputField
type="checkbox"
name="user[licence][categories][]"
value={JSON.stringify(category)}
label={category.category}
checked={localUser.licence.categories != null &&
localUser.licence.categories.some(
(cat) => cat.category === category.category
)}
/>
{#if hasPrivilige(localUser, PERMISSIONS.Member)}
<div class="tab-content" style="display: {activeTab === 'licence' ? 'block' : 'none'}">
<InputField
name="user[licence][status]"
type="select"
label={$t('status')}
bind:value={localUser.licence.status}
options={licenceStatusOptions}
readonly={readonlyUser}
/>
<InputField
name="user[licence][number]"
type="text"
label={$t('licence_number')}
bind:value={localUser.licence.number}
placeholder={$t('placeholder.licence_number')}
toUpperCase={true}
readonly={readonlyUser}
/>
<InputField
name="user[licence][issued_date]"
type="date"
label={$t('issued_date')}
bind:value={localUser.licence.issued_date}
placeholder={$t('placeholder.issued_date')}
readonly={readonlyUser}
/>
<InputField
name="user[licence][expiration_date]"
type="date"
label={$t('expiration_date')}
bind:value={localUser.licence.expiration_date}
placeholder={$t('placeholder.expiration_date')}
readonly={readonlyUser}
/>
<InputField
name="user[licence][country]"
label={$t('country')}
bind:value={localUser.licence.country}
placeholder={$t('placeholder.issuing_country')}
readonly={readonlyUser}
/>
<div class="licence-categories">
<h3>{$t('licence_categories')}</h3>
<div class="checkbox-grid">
{#each Object.entries(groupedCategories) as [, categories], groupIndex}
{#if groupIndex > 0}
<div class="category-break"></div>
{/if}
{#each categories as category}
<div class="checkbox-item">
<div class="checkbox-label-container">
<InputField
type="checkbox"
name="user[licence][categories][]"
value={JSON.stringify(category)}
label={category.category}
checked={localUser.licence.categories != null &&
localUser.licence.categories.some(
(cat) => cat.category === category.category
)}
/>
</div>
<span class="checkbox-description">
{$t(`licenceCategory.${category.category}`)}
</span>
</div>
<span class="checkbox-description">
{$t(`licenceCategory.${category.category}`)}
</span>
</div>
{/each}
{/each}
{/each}
</div>
</div>
</div>
</div>
{/if}
<div class="tab-content" style="display: {activeTab === 'membership' ? 'block' : 'none'}">
<InputField
name="user[membership][status]"
@@ -413,7 +424,7 @@
label={$t('status')}
bind:value={localUser.membership.status}
options={membershipStatusOptions}
readonly={role_id === 0}
readonly={readonlyUser}
/>
<InputField
name="user[membership][subscription_model][name]"
@@ -421,31 +432,33 @@
label={$t('subscription.subscription')}
bind:value={localUser.membership.subscription_model.name}
options={subscriptionModelOptions}
readonly={role_id === 0}
readonly={readonlyUser}
/>
<div class="subscription-info">
<div class="subscription-column">
<p>
<strong>{$t('subscription.monthly_fee')}:</strong>
{selectedSubscriptionModel?.monthly_fee || '-'}
</p>
<p>
<strong>{$t('subscription.hourly_rate')}:</strong>
{selectedSubscriptionModel?.hourly_rate || '-'}
</p>
{#if selectedSubscriptionModel?.included_hours_per_year}
{#if hasPrivilige(editor, PERMISSIONS.Member)}
<div class="subscription-column">
<p>
<strong>{$t('subscription.included_hours_per_year')}:</strong>
{selectedSubscriptionModel?.included_hours_per_year}
<strong>{$t('subscription.monthly_fee')}:</strong>
{selectedSubscriptionModel?.monthly_fee || '-'}
</p>
{/if}
{#if selectedSubscriptionModel?.included_hours_per_month}
<p>
<strong>{$t('subscription.included_hours_per_month')}:</strong>
{selectedSubscriptionModel?.included_hours_per_month}
<strong>{$t('subscription.hourly_rate')}:</strong>
{selectedSubscriptionModel?.hourly_rate || '-'}
</p>
{/if}
</div>
{#if selectedSubscriptionModel?.included_hours_per_year}
<p>
<strong>{$t('subscription.included_hours_per_year')}:</strong>
{selectedSubscriptionModel?.included_hours_per_year}
</p>
{/if}
{#if selectedSubscriptionModel?.included_hours_per_month}
<p>
<strong>{$t('subscription.included_hours_per_month')}:</strong>
{selectedSubscriptionModel?.included_hours_per_month}
</p>
{/if}
</div>
{/if}
<div class="subscription-column">
<p>
<strong>{$t('details')}:</strong>
@@ -465,7 +478,7 @@
label={$t('start')}
bind:value={localUser.membership.start_date}
placeholder={$t('placeholder.start_date')}
readonly={role_id === 0}
readonly={readonlyUser}
/>
<InputField
name="user[membership][end_date]"
@@ -473,16 +486,18 @@
label={$t('end')}
bind:value={localUser.membership.end_date}
placeholder={$t('placeholder.end_date')}
readonly={role_id === 0}
/>
<InputField
name="user[membership][parent_member_id]"
type="number"
label={$t('parent_member_id')}
bind:value={localUser.membership.parent_member_id}
placeholder={$t('placeholder.parent_member_id')}
readonly={role_id === 0}
readonly={readonlyUser}
/>
{#if hasPrivilige(editor, PERMISSIONS.Member)}
<InputField
name="user[membership][parent_member_id]"
type="number"
label={$t('parent_member_id')}
bind:value={localUser.membership.parent_member_id}
placeholder={$t('placeholder.parent_member_id')}
readonly={readonlyUser}
/>
{/if}
</div>
<div class="tab-content" style="display: {activeTab === 'bankaccount' ? 'block' : 'none'}">
<InputField
@@ -516,7 +531,7 @@
label={$t('mandate_reference')}
bind:value={localUser.bank_account.mandate_reference}
placeholder={$t('placeholder.mandate_reference')}
readonly={role_id === 0}
readonly={readonlyUser}
/>
<InputField
name="user[bank_account][mandate_date_signed]"