working on userform

This commit is contained in:
Sockenklaus
2023-07-11 22:28:58 +02:00
parent 428ab06fcc
commit 3a85d2c196
8 changed files with 134 additions and 35 deletions

View File

@@ -6,20 +6,20 @@ export default class UsersController {
public async index({ inertia, bouncer }: HttpContextContract) { public async index({ inertia, bouncer }: HttpContextContract) {
await bouncer.with('UserPolicy').authorize('index') await bouncer.with('UserPolicy').authorize('index')
const users = await Database const users = await Database
.from('users') .from('users')
.select('id', 'username', 'is_admin') .select('id', 'username', 'is_admin')
return inertia.render('Users/Index', { users }) return inertia.render('Users/Index', { users })
} }
public async create({ auth, inertia }: HttpContextContract) { public async create({ inertia, bouncer }: HttpContextContract) {
if(auth.user?.isAdmin) { await bouncer
inertia.render('Users/Create') .with('UserPolicy')
} else { .authorize('create')
} return inertia.render('Users/Create')
} }
public async store({}: HttpContextContract) {} public async store({}: HttpContextContract) {}

3
components.d.ts vendored
View File

@@ -10,11 +10,8 @@ declare module 'vue' {
NButton: typeof import('naive-ui')['NButton'] NButton: typeof import('naive-ui')['NButton']
NCheckbox: typeof import('naive-ui')['NCheckbox'] NCheckbox: typeof import('naive-ui')['NCheckbox']
NDataTable: typeof import('naive-ui')['NDataTable'] NDataTable: typeof import('naive-ui')['NDataTable']
NDivider: typeof import('naive-ui')['NDivider']
NForm: typeof import('naive-ui')['NForm'] NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem'] NFormItem: typeof import('naive-ui')['NFormItem']
NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid']
NInput: typeof import('naive-ui')['NInput'] NInput: typeof import('naive-ui')['NInput']
NMenu: typeof import('naive-ui')['NMenu'] NMenu: typeof import('naive-ui')['NMenu']
NMessageProvider: typeof import('naive-ui')['NMessageProvider'] NMessageProvider: typeof import('naive-ui')['NMessageProvider']

View File

@@ -10,6 +10,7 @@
</template> </template>
<script setup> <script setup>
import { renderIcon } from '@/util'
import { NIcon } from 'naive-ui' import { NIcon } from 'naive-ui'
import { Link, usePage } from '@inertiajs/vue3' import { Link, usePage } from '@inertiajs/vue3'
import { h, ref } from 'vue'; import { h, ref } from 'vue';
@@ -36,7 +37,7 @@
() => "Veranstaltungen" () => "Veranstaltungen"
), ),
key: '/events', key: '/events',
icon: renderIcon(Events) icon: () => { return renderIcon(Events) }
}) })
if(user.is_admin) menuOptions.push({ if(user.is_admin) menuOptions.push({
@@ -49,13 +50,13 @@
() => "Benutzer" () => "Benutzer"
), ),
key: '/users', key: '/users',
icon: renderIcon(Users) icon: () => { return renderIcon(Users) }
}) })
menuOptions.push({ menuOptions.push({
label: "Einstellungen", label: "Einstellungen",
key: "einstellungen", key: "einstellungen",
icon: renderIcon(Settings), icon: () => { return renderIcon(Settings) },
children: [{ children: [{
label: () => h( label: () => h(
Link, { Link, {
@@ -66,7 +67,7 @@
() => "Mein Profil" () => "Mein Profil"
), ),
key: 'profile', key: 'profile',
icon: renderIcon(Profile) icon: () => { return renderIcon(Profile) }
}, },
{ {
@@ -79,15 +80,15 @@
() => "Abmelden" () => "Abmelden"
), ),
key: '/logout', key: '/logout',
icon: renderIcon(Logout) icon: () => { return renderIcon(Logout) }
}] }]
}) })
function renderIcon(icon) { /*function renderIcon(icon) {
return () => h(NIcon, null, { default: () => h(icon) }) return () => h(NIcon, null, { default: () => h(icon) })
} }*/
</script> </script>

View File

@@ -0,0 +1,74 @@
<template>
<n-form
:model="userModel"
label-placement="left"
require-mark-placement="right-hanging"
label-width="auto"
>
<n-form-item label="Benutzername" path="username">
<n-input
v-model:value="userModel.username"
/>
</n-form-item>
<n-form-item label="Ist Admin?" path="is_admin">
<n-checkbox v-model:checked="userModel.is_admin" />
</n-form-item>
<n-form-item label="Passwort" path="password">
<n-input
type="password"
show-password-on="mouseclick"
placeholder="Passwort"
v-model:value="userModel.password"
/>
</n-form-item>
<n-form-item>
<n-input
type="password"
show-password-on="mouseclick"
placeholder="Passwort wiederholen"
v-model:value="userModel.password_repeat"
/>
</n-form-item>
</n-form>
</template>
<script setup>
const props = defineProps({
userModel: Object
})
const rules = {
username: [{
required: true,
message: "Benutzername ist erforderlich",
}],
password: [{
required: true,
message: "Passwort ist erforderlich",
}],
password_repeat: [{
required: true,
message: "Wiederholtes Passwort ist erforderlich",
trigger: ["input", "blur"],
},{
validator: validatePassword,
message: "Passwörter stimmen nicht überein",
trigger: "input",
},{
validator: validatePassword,
message: "Passwörter stimmen nicht überein",
trigger: ["blur", "password-input"],
}]
}
function validatePassword(rule, value) {
return (!!userModel.password
&& userModel.password.startsWith(value)
&& userModel.password.lenght >= value.length)
|| (userModel.password === value)
}
</script>

View File

@@ -1,3 +1,22 @@
<template> <template>
<div class="flex justify-between mb-2">
<n-button
>
</n-button>
<n-button
>
Speichern
</n-button>
</div>
</template> </template>
<script setup>
import BELayout from '@/layouts/BELayout.vue'
import UserForm from '@/components/UserForm.vue'
import { renderIcon } from '@/util'
defineOptions({ layout: BELayout })
</script>

View File

@@ -4,6 +4,16 @@
:messages="props.flashMessages" :messages="props.flashMessages"
/> />
</n-message-provider> </n-message-provider>
<div class="flex flex-row-reverse mb-2">
<n-button
class="items-end"
secondary
type="primary"
:renderIcon="() => { return renderIcon(Plus) }"
:onClick="() => { router.get('/users/create') }"
>
Neuer Benutzer</n-button>
</div>
<n-data-table <n-data-table
:columns="columns" :columns="columns"
:data="users" :data="users"
@@ -23,6 +33,7 @@ import {
AdminPanelSettingsFilled as Admin, AdminPanelSettingsFilled as Admin,
EditRound as Edit, EditRound as Edit,
DeleteRound as Delete, DeleteRound as Delete,
PlusRound as Plus,
} from '@vicons/material' } from '@vicons/material'
defineOptions({ layout: BELayout }) defineOptions({ layout: BELayout })
@@ -36,10 +47,7 @@ const columns = [
align: "center", align: "center",
render (row) { render (row) {
if(row.is_admin) { if(row.is_admin) {
return h( return renderIcon(Admin, "align-middle")
NIcon,
{ size: 20, component: Admin, class: "align-middle" }
)
} }
} }
}, },
@@ -59,7 +67,7 @@ const columns = [
class: "invisible group-hover:visible align-middle", class: "invisible group-hover:visible align-middle",
circle: true, circle: true,
onClick: () => { clickEdit(row.id) }, onClick: () => { clickEdit(row.id) },
renderIcon: () => { return h(NIcon, { component: Edit, size: 20 }) }, renderIcon: () => { return renderIcon(Edit) },
}, },
) )
arr[1] = h( arr[1] = h(
@@ -70,7 +78,7 @@ const columns = [
circle: true, circle: true,
type: "error", type: "error",
onClick: () => { clickDelete(row.id) }, onClick: () => { clickDelete(row.id) },
renderIcon: () => { return h(NIcon, { component: Delete, size: 20 }) }, renderIcon: () => { return renderIcon(Delete) },
}, },
) )
return arr return arr
@@ -86,4 +94,8 @@ function clickDelete(id){
console.log("Delete clicked: "+id) console.log("Delete clicked: "+id)
} }
function renderIcon(icon, className = "") {
return h(NIcon, { component: icon, class: className, size: 20 })
}
</script> </script>

View File

@@ -1,10 +0,0 @@
import type { DateTime } from 'luxon'
export type User = {
id: Number,
username: String,
is_admin: Boolean,
updated_at: DateTime,
created_at: DateTime,
remember_me_token: String | null,
}

View File

@@ -0,0 +1,6 @@
import { h } from "vue"
import { NIcon } from 'naive-ui'
export function renderIcon(icon, className = "", size = 20) {
return h(NIcon, { component: icon, class: className, size: size })
}