implemented user list and editing other users for admin

This commit is contained in:
2025-07-02 22:08:36 +02:00
parent 10c24dd93d
commit ea6ca9e45d
8 changed files with 162 additions and 69 deletions

View File

@@ -1,19 +1,102 @@
<script>
import { t } from '../../translations.svelte.js';
import { useTinyRouter } from 'svelte-tiny-router';
import { onMount } from 'svelte';
import { checkUser } from '../../user.svelte.js';
const router = useTinyRouter();
let { user_id } = $props();
let editUser = $state(null);
let options = $state([]);
let sent = $state(false);
let caption = $state(t('user.save_user'));
onMount(async () => {
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/${user.id}`;
const resp = await fetch(url,{credentials:include});
let url = `${location.protocol}//${location.host.replace('5173','8080')}/themes.json`;
let resp = await fetch(url);
if (resp.ok){
const json = await resp.json();
const arr = await resp.json();
for (let entry of arr){
const value = entry.value;
const caption = entry.caption ? entry.caption : value;
options.push({caption:caption,value:value})
}
}
});
url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/${user_id}`;
resp = await fetch(url,{credentials:'include'});
if (resp.ok) editUser = await resp.json();
});
async function save(elem){
sent = true;
caption = t('user.data_sent');
let url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/${user_id}`;
let resp = await fetch(url,{
method: 'PATCH',
credentials: 'include',
body: JSON.stringify(editUser)
});
if (resp.ok){
caption = t('user.saved');
checkUser();
router.navigate('/user');
} else {
caption = t('user.failed');
}
}
</script>
<fieldset>
<legend>{t('user.editing')} {user_id}</legend>
…Edit form here…
<legend>{t('user.editing',user_id)}</legend>
{#if editUser}
<table>
<tbody>
<tr>
<th>{t('user.id')}</th>
<td>{editUser.id}</td>
</tr>
<tr>
<th>{t('user.name')}</th>
<td>
<input type="text" bind:value={editUser.name} />
</td>
</tr>
<tr>
<th>{t('user.email')}</th>
<td>
<input type="text" bind:value={editUser.email} />
</td>
</tr>
<tr>
<th>{t('user.language')}</th>
<td>
<input type="text" bind:value={editUser.language} />
</td>
</tr>
<tr>
<th>{t('user.password')}</th>
<td>
<input type="password" bind:value={editUser.password} />
</td>
</tr>
<tr>
<th>{t('user.theme')}</th>
<td>
<select bind:value={editUser.theme}>
{#each options as entry,i}
<option value={entry.value}>{entry.caption}</option>
{/each}
</select>
</td>
</tr>
</tbody>
</table>
<button onclick={save} disabled={sent}>{caption}</button>
{:else}
{t('user.loading_data')}
{/if}
</fieldset>

View File

@@ -6,18 +6,21 @@
let oldPass = $state("");
let newPass = $state("");
let repeat = $state("");
let caption = $state(t('user.update'));
let oldEmpty = $derived(!/\S/.test(oldPass));
let newEmpty = $derived(!/\S/.test(newPass));
let mismatch = $derived(newPass != repeat);
let error = $state("");
let sent = $state(false);
function abort(){
editPassword = false;
}
async function submit(){
caption = t('user.data_sent');
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/password`;
const data = {
old: oldPass,
@@ -28,11 +31,11 @@
body: JSON.stringify(data),
credentials: 'include'
});
if (resp.ok){
const json = await resp.json();
console.log(json);
caption = t('user.saved');
} else {
error = await resp.text();
caption = t('user.failed');
}
}
</script>
@@ -63,8 +66,8 @@
<span class="error">{t('user.mismatch')}</span>
{/if}
</label>
<button onclick={submit} disabled={oldEmpty||newEmpty||mismatch}>{t('user.update')}</button>
<button onclick={abort}>{t('user.abort')}</button>
<button onclick={submit} disabled={sent||oldEmpty||newEmpty||mismatch}>{caption}</button>
<button onclick={abort} disabled={sent}>{t('user.abort')}</button>
{#if error}
<span class="error">{error}</span>
{/if}

View File

@@ -1,10 +1,13 @@
<script>
import { t } from '../../translations.svelte.js';
import { user } from '../../user.svelte.js';
import ClickInput from '../../Components/ClickInput.svelte';
import ClickSelect from '../../Components/ClickSelect.svelte';
import { useTinyRouter } from 'svelte-tiny-router';
import EditPassword from './EditPassword.svelte';
import UserList from './List.svelte';
const router = useTinyRouter();
let editPassword = false;
async function patch(changeset){
@@ -31,7 +34,7 @@
<fieldset>
<legend>
{t('user.profile')}
{t('user.your_profile')} <button onclick={() => router.navigate(`/user/${user.id}/edit`)}>{t('user.edit')}</button>
</legend>
<table>
<tbody>
@@ -41,9 +44,7 @@
</tr>
<tr>
<th>{t('user.name')}</th>
<td>
<ClickInput key='name' value={user.name} onUpdate={patch} />
</td>
<td>{user.name}</td>
</tr>
<tr>
<th>{t('user.login')}</th>
@@ -51,21 +52,15 @@
</tr>
<tr>
<th>{t('user.email')}</th>
<td>
<ClickInput key='email' value={user.email} onUpdate={patch} />
</td>
<td>{user.email}</td>
</tr>
<tr>
<th>{t('user.language')}</th>
<td>
<ClickInput key='language' value={user.language} onUpdate={patch} />
</td>
<td>{user.language}</td>
</tr>
<tr>
<th>{t('user.theme')}</th>
<td>
<ClickSelect key='theme' value={user.theme} fetchOptions={fetchThemes} onUpdate={patch} />
</td>
<td>{user.theme}</td>
</tr>
<tr>
<th>{t('user.password')}</th>