136 lines
3.7 KiB
Vue
136 lines
3.7 KiB
Vue
<script setup lang="ts">
|
|
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
|
import type { DocumentUploadData, DropdownSelectable } from "@/types";
|
|
import { reactive } from "vue";
|
|
import { useI18n } from "vue-i18n";
|
|
|
|
interface Props {
|
|
learningSequences: DropdownSelectable[];
|
|
showUploadErrorMessage: boolean;
|
|
isUploading: boolean;
|
|
}
|
|
|
|
const { t } = useI18n();
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
learningSequences: () => [],
|
|
showUploadErrorMessage: false,
|
|
isUploading: false,
|
|
});
|
|
|
|
const emit = defineEmits<{
|
|
(e: "formSubmit", data: DocumentUploadData): void;
|
|
}>();
|
|
|
|
const formData = reactive<DocumentUploadData>({
|
|
file: null,
|
|
name: "",
|
|
learningSequence: {
|
|
id: -1,
|
|
name: t("circlePage.documents.chooseSequence"),
|
|
},
|
|
});
|
|
|
|
const formErrors = reactive({
|
|
file: false,
|
|
name: false,
|
|
learningSequence: false,
|
|
});
|
|
|
|
function fileChange(e: Event) {
|
|
const target = e.target as HTMLInputElement;
|
|
if (target === null || target.files === null) {
|
|
return;
|
|
}
|
|
|
|
formData.file = target.files.length > 0 ? target.files[0] : null;
|
|
}
|
|
|
|
function submitForm() {
|
|
if (!validateForm()) {
|
|
return;
|
|
}
|
|
emit("formSubmit", formData);
|
|
resetFormErrors();
|
|
}
|
|
|
|
function validateForm() {
|
|
formErrors.file = formData.file === null;
|
|
formErrors.learningSequence = formData.learningSequence.id === -1;
|
|
formErrors.name = formData.name === "";
|
|
|
|
for (const [_name, value] of Object.entries(formErrors)) {
|
|
if (value) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function resetFormErrors() {
|
|
for (let [_name, value] of Object.entries(formErrors)) {
|
|
value = false;
|
|
}
|
|
}
|
|
|
|
function showFileInformation() {
|
|
return formData.file || formErrors.file;
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<form @submit.prevent="submitForm()">
|
|
<label class="block text-bold" for="upload">
|
|
{{ $t("circlePage.documents.fileLabel") }}
|
|
</label>
|
|
<div class="mb-4 btn-secondary mt-4 text-xl relative cursor-pointer">
|
|
<input @change="fileChange" id="upload" type="file" class="absolute opacity-0" />
|
|
{{ $t("circlePage.documents.modalAction") }}
|
|
</div>
|
|
<div v-if="showFileInformation()" class="mb-4">
|
|
<div v-if="formData.file">
|
|
<p>{{ formData.file.name }}</p>
|
|
</div>
|
|
<div v-if="formErrors.file">
|
|
<p class="text-red-700">{{ $t("circlePage.documents.selectFile") }}</p>
|
|
</div>
|
|
</div>
|
|
<p class="mb-8">{{ $t("circlePage.documents.maxFileSize") }}</p>
|
|
<div class="mb-8">
|
|
<label class="block text-bold mb-4" for="name">
|
|
{{ $t("circlePage.documents.modalFileName") }}
|
|
</label>
|
|
<input v-model="formData.name" id="name" type="text" class="w-1/2 mb-2" />
|
|
<p>{{ $t("circlePage.documents.modalNameInformation") }}</p>
|
|
<div v-if="formErrors.name">
|
|
<p class="text-red-700">{{ $t("circlePage.documents.chooseName") }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="mb-8">
|
|
<label class="block text-bold mb-4" for="learningsequnce">
|
|
{{ $t("general.learningSequence") }}
|
|
</label>
|
|
<ItDropdownSelect
|
|
v-model="formData.learningSequence"
|
|
class="w-full lg:w-96 mt-4 lg:mt-0"
|
|
:items="props.learningSequences"
|
|
></ItDropdownSelect>
|
|
<div v-if="formErrors.learningSequence">
|
|
<p class="text-red-700">
|
|
{{ $t("circlePage.documents.chooseLearningSequence") }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div v-if="showUploadErrorMessage">
|
|
<p class="text-red-700 mb-4">
|
|
{{ $t("circlePage.documents.uploadErrorMessage") }}
|
|
</p>
|
|
</div>
|
|
<div class="-mx-8 px-8 pt-4 border-t">
|
|
<button class="btn-primary text-xl mb-0" :disabled="isUploading">
|
|
{{ $t("general.save") }}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</template>
|