130 lines
5.6 KiB
Svelte
130 lines
5.6 KiB
Svelte
|
|
<script>
|
||
|
|
let { users = [], adminPath = 'loom', status = null, errors = [] } = $props();
|
||
|
|
|
||
|
|
function deleteUser(id, name) {
|
||
|
|
if (confirm(`Are you sure you want to delete user "${name}"?`)) {
|
||
|
|
const form = document.createElement('form');
|
||
|
|
form.method = 'POST';
|
||
|
|
const baseUrl = window.location.origin.endsWith('/') ? window.location.origin : `${window.location.origin}/`;
|
||
|
|
const path = adminPath.startsWith('/') ? adminPath.substring(1) : adminPath;
|
||
|
|
const url = `${baseUrl}${path}/users/${id}`;
|
||
|
|
form.action = url;
|
||
|
|
|
||
|
|
const methodInput = document.createElement('input');
|
||
|
|
methodInput.type = 'hidden';
|
||
|
|
methodInput.name = '_method';
|
||
|
|
methodInput.value = 'DELETE';
|
||
|
|
|
||
|
|
const tokenInput = document.createElement('input');
|
||
|
|
tokenInput.type = 'hidden';
|
||
|
|
tokenInput.name = '_token';
|
||
|
|
tokenInput.value = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
||
|
|
|
||
|
|
form.appendChild(methodInput);
|
||
|
|
form.appendChild(tokenInput);
|
||
|
|
document.body.appendChild(form);
|
||
|
|
form.submit();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<div class="ui container">
|
||
|
|
<div class="ui grid">
|
||
|
|
<div class="sixteen wide column">
|
||
|
|
<h1 class="ui header">
|
||
|
|
<i class="users icon"></i>
|
||
|
|
<div class="content">
|
||
|
|
User Management
|
||
|
|
<div class="sub header">Manage system users and their assigned roles</div>
|
||
|
|
</div>
|
||
|
|
</h1>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="sixteen wide column">
|
||
|
|
{#if status}
|
||
|
|
<div class="ui positive message">
|
||
|
|
<i class="close icon"></i>
|
||
|
|
<p>{status}</p>
|
||
|
|
</div>
|
||
|
|
{/if}
|
||
|
|
|
||
|
|
{#if errors && errors.length > 0}
|
||
|
|
<div class="ui negative message">
|
||
|
|
<i class="close icon"></i>
|
||
|
|
<ul class="list">
|
||
|
|
{#each errors as error}
|
||
|
|
<li>{error}</li>
|
||
|
|
{/each}
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
{/if}
|
||
|
|
|
||
|
|
<div class="ui secondary menu">
|
||
|
|
<div class="right menu">
|
||
|
|
<a href="{window.location.origin.endsWith('/') ? window.location.origin : window.location.origin + '/'}{adminPath.startsWith('/') ? adminPath.substring(1) : adminPath}/users/create" class="ui primary button">
|
||
|
|
<i class="user plus icon"></i> New User
|
||
|
|
</a>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{#if users.length === 0}
|
||
|
|
<div class="ui placeholder segment">
|
||
|
|
<div class="ui icon header">
|
||
|
|
<i class="users outline icon"></i>
|
||
|
|
No users found in the system.
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
{:else}
|
||
|
|
<table class="ui celled table">
|
||
|
|
<thead>
|
||
|
|
<tr>
|
||
|
|
<th>Name</th>
|
||
|
|
<th>Email</th>
|
||
|
|
<th>Roles</th>
|
||
|
|
<th>Created At</th>
|
||
|
|
<th class="collapsing">Actions</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody>
|
||
|
|
{#each users as user}
|
||
|
|
<tr>
|
||
|
|
<td>
|
||
|
|
<strong>{user.name}</strong>
|
||
|
|
{#if user.is_protected}
|
||
|
|
<div class="ui mini basic label" title="Protected User">
|
||
|
|
<i class="lock icon"></i> Protected
|
||
|
|
</div>
|
||
|
|
{/if}
|
||
|
|
</td>
|
||
|
|
<td>{user.email}</td>
|
||
|
|
<td>
|
||
|
|
{#each user.roles as role}
|
||
|
|
<div class="ui tiny label">{role}</div>
|
||
|
|
{/each}
|
||
|
|
</td>
|
||
|
|
<td>{user.created_at}</td>
|
||
|
|
<td>
|
||
|
|
<div class="ui small basic icon buttons">
|
||
|
|
<a href="{window.location.origin.endsWith('/') ? window.location.origin : window.location.origin + '/'}{adminPath.startsWith('/') ? adminPath.substring(1) : adminPath}/users/{user.id}/edit" class="ui button" title="Edit">
|
||
|
|
<i class="edit icon"></i>
|
||
|
|
</a>
|
||
|
|
{#if !user.is_protected}
|
||
|
|
<button class="ui button" title="Delete" onclick={() => deleteUser(user.id, user.name)}>
|
||
|
|
<i class="trash icon"></i>
|
||
|
|
</button>
|
||
|
|
{:else}
|
||
|
|
<button class="ui disabled button" title="Protected users cannot be deleted">
|
||
|
|
<i class="trash icon"></i>
|
||
|
|
</button>
|
||
|
|
{/if}
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
</tr>
|
||
|
|
{/each}
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
{/if}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|