Skip to content
Snippets Groups Projects

Resolve "Create user"

Merged Daniel Göbel requested to merge feature/119-create-user into main
5 files
+ 194
11
Compare changes
  • Side-by-side
  • Inline
Files
5
+ 171
0
<script setup lang="ts">
import { RoleEnum, type UserIn, type UserOutExtended } from "@/client";
import { onMounted, reactive, ref } from "vue";
import { Modal, Toast } from "bootstrap";
import BootstrapModal from "@/components/modals/BootstrapModal.vue";
import { useUserStore } from "@/stores/users";
import BootstrapToast from "@/components/BootstrapToast.vue";
let modal: Modal | null = null;
const createUserForm = ref<HTMLFormElement | undefined>(undefined);
let successToast: Toast | undefined;
let errorToast: Toast | undefined;
const userRepository = useUserStore();
const formState = reactive<{
loading: boolean;
user: UserIn;
errorMessage?: string;
registeredUserName: string;
validated: boolean;
}>({
loading: false,
errorMessage: "",
validated: false,
registeredUserName: "",
user: {
display_name: "",
email: "",
roles: [RoleEnum.USER],
},
});
const props = defineProps<{
modalId: string;
}>();
const emit = defineEmits<{
(e: "user-created", user: UserOutExtended): void;
}>();
function createUser() {
formState.validated = true;
if (createUserForm.value?.checkValidity()) {
formState.loading = true;
formState.registeredUserName = formState.user.display_name;
userRepository
.createUser(formState.user)
.then((user) => {
emit("user-created", user);
formState.validated = false;
formState.user = {
display_name: "",
email: "",
roles: [RoleEnum.USER],
};
successToast?.show();
modal?.hide();
})
.catch((err) => {
formState.errorMessage = err.body?.detail;
errorToast?.show();
})
.finally(() => {
formState.loading = false;
});
}
}
onMounted(() => {
modal = Modal.getOrCreateInstance(`#${props.modalId}`);
successToast = new Toast("#create-user-success-toast");
errorToast = new Toast("#create-user-error-toast");
});
</script>
<template>
<bootstrap-toast toast-id="create-user-success-toast">
Successfully registered user {{ formState.registeredUserName }}
</bootstrap-toast>
<bootstrap-toast toast-id="create-user-error-toast" color-class="danger">
<template #default
>Couldn't regsiter user
{{ formState.registeredUserName }}
</template>
<template #body>Error: {{ formState.errorMessage }}</template>
</bootstrap-toast>
<bootstrap-modal
:modalId="props.modalId"
:static-backdrop="true"
modal-label="Create user"
>
<template #header>Register a user</template>
<template #body>
<form
id="create-user-form"
@submit.prevent="createUser()"
:class="{ 'was-validated': formState.validated }"
ref="createUserForm"
novalidate
>
<div class="mb-3">
<label for="create-user-name" class="form-label">Name</label>
<input
type="text"
class="form-control"
id="create-user-name"
minlength="3"
maxlength="256"
required
placeholder="John Doe"
v-model="formState.user.display_name"
/>
<div class="invalid-feedback">Please choose a name.</div>
</div>
<div class="mb-3">
<label for="create-user-email" class="form-label"
>Email address</label
>
<input
type="email"
class="form-control"
id="create-user-email"
required
placeholder="name@example.com"
minlength="3"
maxlength="256"
v-model="formState.user.email"
/>
<div class="invalid-feedback">
Please provide a valid email address.
</div>
</div>
<div class="mb-3">
<div class="mb-1">Roles:</div>
<div
class="form-check"
v-for="role in Object.values(RoleEnum)"
:key="role"
>
<input
class="form-check-input"
type="checkbox"
:value="role"
:id="`create-user-role-${role}`"
v-model="formState.user.roles"
/>
<label class="form-check-label" :for="`create-user-role-${role}`">
{{ role.toUpperCase() }}
</label>
</div>
</div>
</form>
</template>
<template #footer>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
</button>
<button
type="submit"
form="create-user-form"
class="btn btn-primary"
:disabled="formState.loading"
>
Save
</button>
</template>
</bootstrap-modal>
</template>
<style scoped></style>
Loading