mirror of
https://github.com/grey-cat-1908/formaptix-web.git
synced 2024-09-22 19:21:59 +03:00
view form & text question designs
This commit is contained in:
parent
bc63923d45
commit
3f5642ab35
6 changed files with 230 additions and 65 deletions
|
@ -111,7 +111,7 @@ async function submitForm() {
|
|||
margin-bottom: 30px;
|
||||
|
||||
&--btn {
|
||||
color: var(--color-red);
|
||||
//color: var(--color-red);
|
||||
transition: 0.25s ease;
|
||||
|
||||
&:hover {
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
<template>
|
||||
<div class="text-question-component">
|
||||
<input
|
||||
type="text"
|
||||
:value="modelValue"
|
||||
readonly
|
||||
/>
|
||||
<input type="text" :value="modelValue" readonly />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
<template>
|
||||
<div class="text-question-component">
|
||||
<div class="text-question">
|
||||
<input
|
||||
class="text-question-input"
|
||||
type="text"
|
||||
v-model="inputValue"
|
||||
:maxlength="maxLength"
|
||||
:required="isRequired"
|
||||
@input="validateInput"
|
||||
@blur="validateInput"
|
||||
placeholder="Ваш ответ"
|
||||
/>
|
||||
<div v-if="error" class="error">{{ error }}</div>
|
||||
<p v-if="error" class="text-question-error"><PhXCircle :size="23" />{{ error }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { PhXCircle } from '@phosphor-icons/vue'
|
||||
|
||||
const props = defineProps({
|
||||
minLength: {
|
||||
|
@ -134,15 +137,37 @@ function validateInput() {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.text-question-component {
|
||||
<style scoped lang="scss">
|
||||
.text-question {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
margin-top: 5px;
|
||||
&-error {
|
||||
margin-top: 20px;
|
||||
color: var(--color-red);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 13px;
|
||||
}
|
||||
|
||||
&-input {
|
||||
width: 100%;
|
||||
background: var(--color-main-background);
|
||||
border: 1px solid var(--color-main-border);
|
||||
padding: 10px 20px;
|
||||
font-weight: 200;
|
||||
border-radius: 0.5rem;
|
||||
outline: 0;
|
||||
transition: 0.25s ease;
|
||||
|
||||
&:hover {
|
||||
border: 1px solid var(--color-secondary-border);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border: 1px solid var(--color-third-border);
|
||||
background: var(--color-input-background);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
:root {
|
||||
--color-main: #5c8bfd;
|
||||
--color-text: #181f23;
|
||||
--color-subtext: #646e80;
|
||||
--color-subtext: #727c8e;
|
||||
--color-description: #606b80;
|
||||
--color-alternative-text: #fff;
|
||||
--color-main-background: #efefef;
|
||||
--color-secondary-background: #fff;
|
||||
|
|
|
@ -3,23 +3,29 @@ import { onMounted, ref } from 'vue'
|
|||
import { makeAPIRequest } from '@/utils/http'
|
||||
import FormNotFound from '@/components/FormNotFound.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import TextValue from "@/components/answers/TextValue.vue";
|
||||
import TextValue from '@/components/answers/TextValue.vue'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const data = ref([])
|
||||
const currentPageNumber = ref(0);
|
||||
const currentPageNumber = ref(0)
|
||||
const isAnswerNotFound = ref(true)
|
||||
const mode = ref(0);
|
||||
const mode = ref(0)
|
||||
|
||||
onMounted(async () => {
|
||||
const formResponse = await makeAPIRequest('/answer/get', 'GET', { form_id: Number(route.params.id) }, {}, true)
|
||||
const formResponse = await makeAPIRequest(
|
||||
'/answer/get',
|
||||
'GET',
|
||||
{ form_id: Number(route.params.id) },
|
||||
{},
|
||||
true
|
||||
)
|
||||
if (!formResponse.json || formResponse.status !== 200) {
|
||||
return
|
||||
}
|
||||
data.value = formResponse.json.answers
|
||||
if (data.value.length > 0) {
|
||||
isAnswerNotFound.value = false;
|
||||
isAnswerNotFound.value = false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
@ -30,7 +36,9 @@ onMounted(async () => {
|
|||
<button @click="mode = 0">Отдельный пользователь</button>
|
||||
<div class="" v-if="mode === 0">
|
||||
<button @click="currentPageNumber = Math.max(0, currentPageNumber - 1)"><</button>
|
||||
<button @click="currentPageNumber = Math.min(data.length - 1, currentPageNumber + 1)">></button>
|
||||
<button @click="currentPageNumber = Math.min(data.length - 1, currentPageNumber + 1)">
|
||||
>
|
||||
</button>
|
||||
|
||||
<div class="" v-for="(value, index) in data[currentPageNumber].data.values">
|
||||
<TextValue v-if="value.question_type === 1" v-model="value.value" />
|
||||
|
|
|
@ -7,6 +7,8 @@ import SelectorQuestion from '@/components/forms/SelectorQuestion.vue'
|
|||
import FormNotFound from '@/components/FormNotFound.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import { PhInfo } from '@phosphor-icons/vue'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const data = ref({})
|
||||
|
@ -71,17 +73,26 @@ onMounted(async () => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="view">
|
||||
<div class="container">
|
||||
<FormNotFound v-if="isFormNotFound" />
|
||||
<div v-else>
|
||||
<div v-if="isSent">Форма была успешно отправлена.</div>
|
||||
<div v-else>
|
||||
<div v-if="isSent" class="default-card">Форма была успешно отправлена.</div>
|
||||
<div v-else class="view-form">
|
||||
<div class="view-form-title view-form-container default-card">
|
||||
<div class="view-form-info">
|
||||
<PhInfo :size="23" class="view-form-info--sign" /> Информация о форме
|
||||
</div>
|
||||
<h2>{{ data.name }}</h2>
|
||||
<p>{{ currentPage.text }}</p>
|
||||
|
||||
<form @submit.prevent="submitForm">
|
||||
<div class="" v-for="question in currentPage.questions">
|
||||
</div>
|
||||
<form @submit.prevent="submitForm" class="">
|
||||
<div class="view-form-q view-form-container">
|
||||
<div class="default-card" v-for="question in currentPage.questions">
|
||||
<div class="view-form-q-title">
|
||||
<h3>{{ question.label }}</h3>
|
||||
<p>{{ question.description }}</p>
|
||||
</div>
|
||||
<TextQuestion
|
||||
v-if="question.question_type === 1"
|
||||
:minLength="question.min_length"
|
||||
|
@ -111,11 +122,135 @@ onMounted(async () => {
|
|||
@input="answers[question.id].value = $event"
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" v-if="currentPageNumber === pageCount - 1">Отправить</button>
|
||||
<button type="submit" v-else>Дальше</button>
|
||||
</div>
|
||||
<div class="view-form-btns view-form-container">
|
||||
<div class="view-form-send-space" v-if="currentPageNumber === pageCount - 1">
|
||||
<button type="submit" class="default-button view-form-send">Отправить</button>
|
||||
<div class="view-form-info">
|
||||
<PhInfo :size="23" class="view-form-info--sign" /> Проверьте все данные перед
|
||||
отправкой!
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="default-button view-form-next" v-else>Дальше</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped lang="scss">
|
||||
.default-card {
|
||||
width: 100%;
|
||||
border: 1px solid var(--color-main-border);
|
||||
background: var(--color-secondary-background);
|
||||
padding: 25px;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
.view {
|
||||
margin: 40px 0;
|
||||
&-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
//gap: 25px 0;
|
||||
|
||||
&-container {
|
||||
margin: 0 auto;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
&-title {
|
||||
border: 1px solid var(--color-third-border);
|
||||
//margin-bottom: 20px;
|
||||
|
||||
& h2 {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 11px;
|
||||
color: var(--color-subtext);
|
||||
font-size: 16px;
|
||||
|
||||
&--sign {
|
||||
min-width: 23px;
|
||||
min-height: 23px;
|
||||
}
|
||||
}
|
||||
|
||||
&-q {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px 0;
|
||||
margin: 35px auto;
|
||||
|
||||
&:empty {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
&-title {
|
||||
margin-bottom: 25px;
|
||||
|
||||
& h3 {
|
||||
font-weight: 400;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
& p {
|
||||
color: var(--color-description);
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-send,
|
||||
&-next {
|
||||
border-radius: 1rem;
|
||||
padding: 10px 30px;
|
||||
}
|
||||
|
||||
&-send {
|
||||
padding: 15px 30px;
|
||||
border-radius: 1rem;
|
||||
background: var(--color-main);
|
||||
color: var(--color-alternative-text);
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-space {
|
||||
display: flex;
|
||||
//justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 10px 30px;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
h2 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 380px) {
|
||||
h2 {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in a new issue