bug fix && textarea support

This commit is contained in:
grey-cat-1908 2024-09-20 18:02:17 +03:00
parent d6439f223b
commit fbeed920c5
8 changed files with 77 additions and 29 deletions

View file

@ -4,7 +4,10 @@
<h3 class="form-q-title">{{ label }}</h3> <h3 class="form-q-title">{{ label }}</h3>
<p class="form-q-description">{{ description }}</p> <p class="form-q-description">{{ description }}</p>
</div> </div>
<div class="text-question"> <div v-if="textarea" class="text-question">
<textarea class="text-question-input" :value="modelValue" readonly />
</div>
<div v-else class="text-question">
<input class="text-question-input" type="text" :value="modelValue" readonly /> <input class="text-question-input" type="text" :value="modelValue" readonly />
</div> </div>
</div> </div>
@ -25,6 +28,10 @@ const props = defineProps({
modelValue: { modelValue: {
type: Array, type: Array,
default: () => [] default: () => []
},
textarea: {
type: Boolean,
default: null
} }
}) })
</script> </script>

View file

@ -19,7 +19,8 @@ const props = defineProps({
min_value: 1, min_value: 1,
max_value: 5, max_value: 5,
min_label: null, min_label: null,
max_label: null max_label: null,
textarea: false
} }
} }
}) })
@ -83,6 +84,13 @@ async function submitForm() {
<div class="question-data"> <div class="question-data">
<div class="" v-if="data.question_type === 1"> <div class="" v-if="data.question_type === 1">
<div class=""> <div class="">
<div class="">
<p>Развернутый?</p>
<label class="switch">
<input v-model="data.textarea" type="checkbox" />
<span class="slider"></span>
</label>
</div>
<p>Валидатор</p> <p>Валидатор</p>
<select v-model="data.validator" id="question-type"> <select v-model="data.validator" id="question-type">
<option :value="null">Текст</option> <option :value="null">Текст</option>

View file

@ -3,7 +3,10 @@
<h3 class="form-q-title">{{ label }} <span style="color: red" v-if="required">*</span></h3> <h3 class="form-q-title">{{ label }} <span style="color: red" v-if="required">*</span></h3>
<p class="form-q-description">{{ description }}</p> <p class="form-q-description">{{ description }}</p>
</div> </div>
<div class="text-question"> <div v-if="textarea" class="text-question">
<textarea class="text-question-input" placeholder="Ответ на вопрос" readonly />
</div>
<div v-else class="text-question">
<input class="text-question-input" placeholder="Ответ на вопрос" type="text" readonly /> <input class="text-question-input" placeholder="Ответ на вопрос" type="text" readonly />
</div> </div>
</template> </template>
@ -23,6 +26,10 @@ const props = defineProps({
required: { required: {
type: Boolean, type: Boolean,
default: null default: null
},
textarea: {
type: Boolean,
default: null
} }
}) })
</script> </script>

View file

@ -5,7 +5,21 @@
<p class="form-q-description">{{ description }}</p> <p class="form-q-description">{{ description }}</p>
</div> </div>
<img v-if="imageUrl" :src="imageUrl" alt="image by user" /> <img v-if="imageUrl" :src="imageUrl" alt="image by user" />
<div class="text-question"> <div v-if="isTextarea" class="text-question">
<textarea
class="text-question-input"
v-model="inputValue"
:maxlength="maxLength"
:required="isRequired"
@input="validateInput"
@blur="validateInput"
placeholder="Ваш ответ"
/>
<p v-if="error" class="text-question-error">
<PhXCircle class="text-question-error--sign" :size="23" />{{ error }}
</p>
</div>
<div v-else class="text-question">
<input <input
class="text-question-input" class="text-question-input"
type="text" type="text"
@ -67,6 +81,10 @@ const props = defineProps({
isEmpty: { isEmpty: {
type: Boolean, type: Boolean,
default: false default: false
},
isTextarea: {
type: Boolean,
default: false
} }
}) })

View file

@ -8,7 +8,7 @@ import { makeAPIRequest } from '@/utils/http'
const authStore = useAuthStore() const authStore = useAuthStore()
const userForms = ref([]) const userForms = ref([])
import {PhEye, PhInfo, PhPen, PhPencil, PhTrash, PhUserList} from '@phosphor-icons/vue' import { PhEye, PhInfo, PhPen, PhPencil, PhTrash, PhUserList } from '@phosphor-icons/vue'
onMounted(async () => { onMounted(async () => {
await authStore.prepareStore() await authStore.prepareStore()
@ -53,30 +53,41 @@ async function createForm() {
<h1 class="profile-title">Профиль пользователя</h1> <h1 class="profile-title">Профиль пользователя</h1>
<div class="profile-ctrl-card"> <div class="profile-ctrl-card">
<div class="profile-ctrl-buttons"> <div class="profile-ctrl-buttons">
<button @click="createForm" class="default-button profile-ctrl-btn profile-ctrl-btn--create">Создать форму</button> <button
<!-- <button @click="createForm" class="default-button profile-ctrl-btn profile-ctrl-btn&#45;&#45;creat">Очистить все формы</button>--> @click="createForm"
<button @click="createForm" class="default-button profile-ctrl-btn profile-ctrl-btn--deleteacc">Удалить аккаунт</button> class="default-button profile-ctrl-btn profile-ctrl-btn--create"
>
Создать форму
</button>
<!-- <button @click="createForm" class="default-button profile-ctrl-btn profile-ctrl-btn&#45;&#45;creat">Очистить все формы</button>-->
<button
@click="createForm"
class="default-button profile-ctrl-btn profile-ctrl-btn--deleteacc"
>
Удалить аккаунт
</button>
<div class="profile-ctrl-info"> <div class="profile-ctrl-info">
<PhInfo :size="22" class="profile-ctrl-info--sign" /> После удаления аккаунта вернуть данные невозможно <PhInfo :size="22" class="profile-ctrl-info--sign" /> После удаления аккаунта вернуть
данные невозможно
</div> </div>
</div> </div>
</div> </div>
<div class="profile-cards"> <div class="profile-cards">
<div class="profile-card" v-for="(form, index) in userForms" v-if="userForms.length > 0"> <div class="profile-card" v-for="(form, index) in userForms" v-if="userForms.length > 0">
<div class="profile-card-title"> <div class="profile-card-title">
<!-- <code class="profile-card-num">001</code>--> <!-- <code class="profile-card-num">001</code>-->
{{ form.data.name }} {{ form.data.name }}
</div> </div>
<div class="profile-card-buttons"> <div class="profile-card-buttons">
<button <button
class="profile-card-btn profile-card-btn--upd" class="profile-card-btn profile-card-btn--upd"
@click="$router.push('/form/edit/' + form.id)" @click="$router.push('/form/edit/' + form.id)"
> >
<div class="profile-card-btn-inner"><PhPencil :size="26" /></div> <div class="profile-card-btn-inner"><PhPencil :size="26" /></div>
</button> </button>
<button <button
class="profile-card-btn profile-card-btn--upd" class="profile-card-btn profile-card-btn--upd"
@click="$router.push('/form/edit/' + form.id)" @click="$router.push('/form/answers/' + form.id)"
> >
<div class="profile-card-btn-inner"><PhUserList :size="26" /></div> <div class="profile-card-btn-inner"><PhUserList :size="26" /></div>
</button> </button>
@ -104,7 +115,6 @@ async function createForm() {
margin: 40px 0; margin: 40px 0;
&-ctrl { &-ctrl {
&-info { &-info {
display: flex; display: flex;
align-items: center; align-items: center;
@ -143,15 +153,12 @@ async function createForm() {
border: 1px solid var(--color-third-border); border: 1px solid var(--color-third-border);
} }
@media (max-width: 500px) { @media (max-width: 500px) {
width: 100%; width: 100%;
} }
&--create { &--create {
color: var(--color-main); color: var(--color-main);
} }
&--deleteacc { &--deleteacc {
@ -161,7 +168,6 @@ async function createForm() {
} }
} }
&-cards { &-cards {
margin-top: 30px; margin-top: 30px;
display: flex; display: flex;
@ -181,9 +187,7 @@ async function createForm() {
//cursor: pointer; //cursor: pointer;
&:hover { &:hover {
//background: var(--color-main-border); //background: var(--color-main-border);
} }
@media (max-width: 680px) { @media (max-width: 680px) {
@ -227,9 +231,7 @@ async function createForm() {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
transition: 0.25s ease; transition: 0.25s ease;
&:hover { &:hover {
opacity: 0.7; opacity: 0.7;
@ -238,7 +240,6 @@ async function createForm() {
&--delete { &--delete {
color: var(--color-red); color: var(--color-red);
} }
} }
&-title { &-title {
@ -262,5 +263,4 @@ async function createForm() {
} }
} }
} }
</style> </style>

View file

@ -61,6 +61,7 @@ onMounted(async () => {
v-if="questionsData[value.question_id].question_type === 1" v-if="questionsData[value.question_id].question_type === 1"
:label="questionsData[value.question_id].label" :label="questionsData[value.question_id].label"
:description="questionsData[value.question_id].description" :description="questionsData[value.question_id].description"
:textarea="questionsData[value.question_id].textarea"
v-model="value.value" v-model="value.value"
/> />
<SelectorValue <SelectorValue

View file

@ -125,6 +125,7 @@ onMounted(async () => {
:label="element.label" :label="element.label"
:description="element.description" :description="element.description"
:required="element.required" :required="element.required"
:textarea="element.textarea"
/> />
<SelectorPreview <SelectorPreview
v-if="element.question_type === 2" v-if="element.question_type === 2"

View file

@ -18,7 +18,7 @@ const data = ref({})
const currentPageNumber = ref(0) const currentPageNumber = ref(0)
const pageCount = ref(0) const pageCount = ref(0)
const currentPage = ref({}) const currentPage = ref({})
const answers = ref([]) const answers = ref({})
const isFormNotFound = ref(true) const isFormNotFound = ref(true)
const isSent = ref(false) const isSent = ref(false)
@ -29,7 +29,9 @@ async function prepareNewPage() {
currentPage.value.questions.forEach((q) => { currentPage.value.questions.forEach((q) => {
answers.value[q.id] = { answers.value[q.id] = {
question_id: q.id, question_id: q.id,
question_type: q.question_type question_type: q.question_type,
value: null,
values: null
} }
}) })
} }
@ -120,6 +122,7 @@ onMounted(async () => {
<div class="view-form-q view-form-container"> <div class="view-form-q view-form-container">
<div v-for="question in currentPage.questions"> <div v-for="question in currentPage.questions">
<TextQuestion <TextQuestion
:key="question.id"
v-if="question.question_type === 1" v-if="question.question_type === 1"
:label="question.label" :label="question.label"
:description="question.description" :description="question.description"
@ -128,11 +131,13 @@ onMounted(async () => {
:maxLength="question.max_length" :maxLength="question.max_length"
:validator="question.validator" :validator="question.validator"
:isRequired="question.required" :isRequired="question.required"
:isTextarea="question.textarea"
:isEmpty="emptyQuestions[question.id]" :isEmpty="emptyQuestions[question.id]"
v-model="answers[question.id].value" v-model="answers[question.id].value"
@input="answers[question.id].value = $event" @input="answers[question.id].value = $event"
/> />
<SelectorQuestion <SelectorQuestion
:key="question.id"
v-if="question.question_type === 2" v-if="question.question_type === 2"
:label="question.label" :label="question.label"
:description="question.description" :description="question.description"
@ -146,6 +151,7 @@ onMounted(async () => {
@input="answers[question.id].values = $event" @input="answers[question.id].values = $event"
/> />
<Scale <Scale
:key="question.id"
v-if="question.question_type === 3" v-if="question.question_type === 3"
:label="question.label" :label="question.label"
:description="question.description" :description="question.description"