Versão 0.5 antes do PWA
This commit is contained in:
@@ -8,12 +8,13 @@ export const load: PageServerLoad = async () => {
|
||||
const list = db
|
||||
.select({
|
||||
id: schema.users.id,
|
||||
name: schema.users.name,
|
||||
username: schema.users.username,
|
||||
role: schema.users.role,
|
||||
createdAt: schema.users.createdAt
|
||||
})
|
||||
.from(schema.users)
|
||||
.orderBy(asc(schema.users.username))
|
||||
.orderBy(asc(schema.users.name))
|
||||
.all();
|
||||
|
||||
return {
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
<thead class="table-light text-secondary fw-semibold">
|
||||
<tr>
|
||||
<th class="px-4 py-3">Nome</th>
|
||||
<th class="py-3">Username</th>
|
||||
<th class="py-3">Role</th>
|
||||
<th class="px-4 py-3 text-end" style="width: 120px;">Ações</th>
|
||||
</tr>
|
||||
@@ -67,7 +68,7 @@
|
||||
<tbody>
|
||||
{#if data.users.length === 0}
|
||||
<tr>
|
||||
<td colspan="3" class="text-center py-5 text-muted">
|
||||
<td colspan="4" class="text-center py-5 text-muted">
|
||||
<p class="mb-0">Nenhum utilizador encontrado.</p>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -75,7 +76,10 @@
|
||||
{#each data.users as u}
|
||||
<tr>
|
||||
<td class="px-4 fw-bold text-dark">
|
||||
{u.username}
|
||||
{u.name}
|
||||
</td>
|
||||
<td class="text-secondary">
|
||||
@{u.username}
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-dark-subtle text-dark border px-2.5 py-1.5 rounded-3 fw-semibold">
|
||||
|
||||
@@ -12,6 +12,7 @@ export const load: PageServerLoad = async ({ params }) => {
|
||||
const user = db
|
||||
.select({
|
||||
id: schema.users.id,
|
||||
name: schema.users.name,
|
||||
username: schema.users.username,
|
||||
role: schema.users.role,
|
||||
createdAt: schema.users.createdAt
|
||||
@@ -40,15 +41,16 @@ export const actions: Actions = {
|
||||
default: async ({ params, request }) => {
|
||||
const id = params.id;
|
||||
const data = await request.formData();
|
||||
const name = data.get('name')?.toString().trim();
|
||||
const username = data.get('username')?.toString().trim();
|
||||
const role = data.get('role')?.toString().trim();
|
||||
const password = data.get('password')?.toString();
|
||||
const confirmPassword = data.get('confirmPassword')?.toString();
|
||||
|
||||
if (!username || !role) {
|
||||
if (!name || !username || !role) {
|
||||
return fail(400, {
|
||||
success: false,
|
||||
error: 'Nome de utilizador e Perfil são campos obrigatórios.'
|
||||
error: 'Nome, Nome de utilizador e Perfil são campos obrigatórios.'
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,6 +103,7 @@ export const actions: Actions = {
|
||||
const passwordHash = bcrypt.hashSync(password!, 10);
|
||||
db.update(schema.users)
|
||||
.set({
|
||||
name,
|
||||
username,
|
||||
role,
|
||||
passwordHash
|
||||
@@ -110,6 +113,7 @@ export const actions: Actions = {
|
||||
} else {
|
||||
db.update(schema.users)
|
||||
.set({
|
||||
name,
|
||||
username,
|
||||
role
|
||||
})
|
||||
|
||||
@@ -38,6 +38,20 @@
|
||||
};
|
||||
}}>
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-md-6">
|
||||
<label for="name" class="form-label fw-semibold text-secondary small">Nome Completo <span class="text-danger">*</span></label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
id="name"
|
||||
class="form-control rounded-3 border-2"
|
||||
placeholder="Ex: João Silva"
|
||||
value={form?.name ?? user.name}
|
||||
required
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label for="username" class="form-label fw-semibold text-secondary small">Nome de Utilizador <span class="text-danger">*</span></label>
|
||||
<input
|
||||
@@ -45,7 +59,7 @@
|
||||
name="username"
|
||||
id="username"
|
||||
class="form-control rounded-3 border-2"
|
||||
placeholder="Ex: joao.silva"
|
||||
placeholder="Ex: joao"
|
||||
value={form?.username ?? user.username}
|
||||
required
|
||||
disabled={isLoading}
|
||||
|
||||
@@ -8,14 +8,16 @@ import bcrypt from 'bcrypt';
|
||||
export const actions: Actions = {
|
||||
default: async ({ request }) => {
|
||||
const data = await request.formData();
|
||||
const name = data.get('name')?.toString().trim();
|
||||
const username = data.get('username')?.toString().trim();
|
||||
const role = data.get('role')?.toString().trim();
|
||||
const password = data.get('password')?.toString();
|
||||
const confirmPassword = data.get('confirmPassword')?.toString();
|
||||
|
||||
if (!username || !role || !password || !confirmPassword) {
|
||||
if (!name || !username || !role || !password || !confirmPassword) {
|
||||
return fail(400, {
|
||||
success: false,
|
||||
name,
|
||||
username,
|
||||
role,
|
||||
error: 'Todos os campos obrigatórios devem ser preenchidos.'
|
||||
@@ -25,6 +27,7 @@ export const actions: Actions = {
|
||||
if (role !== 'admin' && role !== 'shift_manager' && role !== 'volunteer') {
|
||||
return fail(400, {
|
||||
success: false,
|
||||
name,
|
||||
username,
|
||||
role,
|
||||
error: 'Perfil selecionado é inválido.'
|
||||
@@ -34,6 +37,7 @@ export const actions: Actions = {
|
||||
if (password !== confirmPassword) {
|
||||
return fail(400, {
|
||||
success: false,
|
||||
name,
|
||||
username,
|
||||
role,
|
||||
error: 'As palavras-passe introduzidas não coincidem.'
|
||||
@@ -43,6 +47,7 @@ export const actions: Actions = {
|
||||
if (password.length < 4) {
|
||||
return fail(400, {
|
||||
success: false,
|
||||
name,
|
||||
username,
|
||||
role,
|
||||
error: 'A palavra-passe deve ter pelo menos 4 caracteres.'
|
||||
@@ -60,6 +65,7 @@ export const actions: Actions = {
|
||||
if (existing) {
|
||||
return fail(400, {
|
||||
success: false,
|
||||
name,
|
||||
username,
|
||||
role,
|
||||
error: 'O nome de utilizador já está a ser utilizado.'
|
||||
@@ -70,6 +76,7 @@ export const actions: Actions = {
|
||||
const passwordHash = bcrypt.hashSync(password, 10);
|
||||
db.insert(schema.users)
|
||||
.values({
|
||||
name,
|
||||
username,
|
||||
role,
|
||||
passwordHash,
|
||||
|
||||
@@ -36,6 +36,20 @@
|
||||
};
|
||||
}}>
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-md-6">
|
||||
<label for="name" class="form-label fw-semibold text-secondary small">Nome Completo <span class="text-danger">*</span></label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
id="name"
|
||||
class="form-control rounded-3 border-2"
|
||||
placeholder="Ex: João Silva"
|
||||
value={form?.name ?? ''}
|
||||
required
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label for="username" class="form-label fw-semibold text-secondary small">Nome de Utilizador <span class="text-danger">*</span></label>
|
||||
<input
|
||||
@@ -43,7 +57,7 @@
|
||||
name="username"
|
||||
id="username"
|
||||
class="form-control rounded-3 border-2"
|
||||
placeholder="Ex: joao.silva"
|
||||
placeholder="Ex: joao"
|
||||
value={form?.username ?? ''}
|
||||
required
|
||||
disabled={isLoading}
|
||||
|
||||
@@ -37,13 +37,13 @@
|
||||
};
|
||||
}}>
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label fw-semibold text-secondary">Utilizador / E-mail</label>
|
||||
<label for="username" class="form-label fw-semibold text-secondary">Nome de Utilizador</label>
|
||||
<input
|
||||
type="text"
|
||||
name="username"
|
||||
id="username"
|
||||
class="form-control form-control-lg rounded-3 border-2"
|
||||
placeholder="Ex: refoodpdn"
|
||||
placeholder="Ex: admin"
|
||||
required
|
||||
disabled={isLoading}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user