mirror of
https://github.com/grey-cat-1908/formaptix-web.git
synced 2024-09-22 19:21:59 +03:00
view page error checking
This commit is contained in:
parent
1e2ee1c2a3
commit
b99f1d403d
7 changed files with 150 additions and 113 deletions
7
src/components/FormNotFound.vue
Normal file
7
src/components/FormNotFound.vue
Normal file
|
@ -0,0 +1,7 @@
|
|||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<h2>Форма недоступна</h2>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
|
@ -7,16 +7,18 @@
|
|||
<div class="rating-options">
|
||||
<label v-for="n in range" :key="n" class="rating-option">
|
||||
<input
|
||||
type="radio"
|
||||
:value="n"
|
||||
v-model="selectedValue"
|
||||
:required="isRequired"
|
||||
@change="updateValue"
|
||||
type="radio"
|
||||
:value="n"
|
||||
v-model="selectedValue"
|
||||
:required="isRequired"
|
||||
@change="updateValue"
|
||||
/>
|
||||
<span>{{ n }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<button v-if="selectedValue !== null" @click="cancelSelection">Отменить выбор</button>
|
||||
<button v-if="selectedValue !== null" @click="cancelSelection">
|
||||
Отменить выбор
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -54,7 +56,7 @@ const emit = defineEmits(['input'])
|
|||
const selectedValue = ref(props.value)
|
||||
|
||||
const range = computed(() => {
|
||||
return Array.from({ length: props.max - props.min + 1 }, (_, i) => props.min + i)
|
||||
return Array.from({length: props.max - props.min + 1}, (_, i) => props.min + i)
|
||||
})
|
||||
|
||||
function updateValue() {
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
<div class="selector-component">
|
||||
<div class="options">
|
||||
<div
|
||||
v-for="(option, index) in options"
|
||||
:key="index"
|
||||
class="option"
|
||||
@click="toggleSelection(index)"
|
||||
:class="{ selected: isSelected(index) }"
|
||||
v-for="(option, index) in options"
|
||||
:key="index"
|
||||
class="option"
|
||||
@click="toggleSelection(index)"
|
||||
:class="{ selected: isSelected(index) }"
|
||||
>
|
||||
<span>{{ option.label }}</span>
|
||||
</div>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<template>
|
||||
<div class="text-question-component">
|
||||
<input
|
||||
type="text"
|
||||
v-model="inputValue"
|
||||
:maxlength="maxLength"
|
||||
:required="isRequired"
|
||||
@input="validateInput"
|
||||
@blur="validateInput"
|
||||
type="text"
|
||||
v-model="inputValue"
|
||||
:maxlength="maxLength"
|
||||
:required="isRequired"
|
||||
@input="validateInput"
|
||||
@blur="validateInput"
|
||||
/>
|
||||
<div v-if="error" class="error">{{ error }}</div>
|
||||
</div>
|
||||
|
@ -50,48 +50,48 @@ function validateTIN(value) {
|
|||
|
||||
if (len === 10) {
|
||||
const checksum =
|
||||
((2 * digits[0] +
|
||||
4 * digits[1] +
|
||||
10 * digits[2] +
|
||||
3 * digits[3] +
|
||||
5 * digits[4] +
|
||||
9 * digits[5] +
|
||||
4 * digits[6] +
|
||||
6 * digits[7] +
|
||||
8 * digits[8]) %
|
||||
11) %
|
||||
10
|
||||
((2 * digits[0] +
|
||||
4 * digits[1] +
|
||||
10 * digits[2] +
|
||||
3 * digits[3] +
|
||||
5 * digits[4] +
|
||||
9 * digits[5] +
|
||||
4 * digits[6] +
|
||||
6 * digits[7] +
|
||||
8 * digits[8]) %
|
||||
11) %
|
||||
10
|
||||
return digits[9] === checksum
|
||||
}
|
||||
|
||||
if (len === 12) {
|
||||
const checksum1 =
|
||||
((7 * digits[0] +
|
||||
2 * digits[1] +
|
||||
4 * digits[2] +
|
||||
10 * digits[3] +
|
||||
3 * digits[4] +
|
||||
5 * digits[5] +
|
||||
9 * digits[6] +
|
||||
4 * digits[7] +
|
||||
6 * digits[8] +
|
||||
8 * digits[9]) %
|
||||
11) %
|
||||
10
|
||||
((7 * digits[0] +
|
||||
2 * digits[1] +
|
||||
4 * digits[2] +
|
||||
10 * digits[3] +
|
||||
3 * digits[4] +
|
||||
5 * digits[5] +
|
||||
9 * digits[6] +
|
||||
4 * digits[7] +
|
||||
6 * digits[8] +
|
||||
8 * digits[9]) %
|
||||
11) %
|
||||
10
|
||||
const checksum2 =
|
||||
((3 * digits[0] +
|
||||
7 * digits[1] +
|
||||
2 * digits[2] +
|
||||
4 * digits[3] +
|
||||
10 * digits[4] +
|
||||
3 * digits[5] +
|
||||
5 * digits[6] +
|
||||
9 * digits[7] +
|
||||
4 * digits[8] +
|
||||
6 * digits[9] +
|
||||
8 * digits[10]) %
|
||||
11) %
|
||||
10
|
||||
((3 * digits[0] +
|
||||
7 * digits[1] +
|
||||
2 * digits[2] +
|
||||
4 * digits[3] +
|
||||
10 * digits[4] +
|
||||
3 * digits[5] +
|
||||
5 * digits[6] +
|
||||
9 * digits[7] +
|
||||
4 * digits[8] +
|
||||
6 * digits[9] +
|
||||
8 * digits[10]) %
|
||||
11) %
|
||||
10
|
||||
return digits[10] === checksum1 && digits[11] === checksum2
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ const router = createRouter({
|
|||
component: () => import('@/views/Index.vue')
|
||||
},
|
||||
{
|
||||
path: '/form/view',
|
||||
path: '/form/view/:id',
|
||||
name: 'View Form',
|
||||
component: () => import('@/views/form/View.vue')
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
export function makeAPIRequest(
|
||||
path: string = '',
|
||||
method: string = 'GET',
|
||||
query: any = {},
|
||||
body: any = {},
|
||||
useAuthorization: boolean = false
|
||||
): Promise<any> {
|
||||
path: string = '',
|
||||
method: string = 'GET',
|
||||
query: any = {},
|
||||
body: any = {},
|
||||
useAuthorization: boolean = false
|
||||
): Promise < any > {
|
||||
return new Promise(async (resolve, _) => {
|
||||
let options: any = {
|
||||
method,
|
||||
|
@ -23,13 +23,18 @@ export function makeAPIRequest(
|
|||
finalPath += '?' + new URLSearchParams(query)
|
||||
}
|
||||
|
||||
const r = await fetch(finalPath, options)
|
||||
.then((r) => r.json())
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
return resolve({ error: 'CRITICAL_ERROR' })
|
||||
})
|
||||
|
||||
return resolve(r.data)
|
||||
await fetch(finalPath, options)
|
||||
.then(async (r) => {
|
||||
return resolve({
|
||||
json: await r.json(),
|
||||
status: r.status
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
return resolve({
|
||||
error: 'CRITICAL_ERROR'
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
|
@ -4,11 +4,18 @@ import { makeAPIRequest } from '@/utils/http'
|
|||
import Scale from '@/components/forms/ScaleQuestion.vue'
|
||||
import TextQuestion from '@/components/forms/TextQuestion.vue'
|
||||
import SelectorQuestion from '@/components/forms/SelectorQuestion.vue'
|
||||
import FormNotFound from '@/components/FormNotFound.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const data = ref({})
|
||||
const currentPageNumber = ref(0)
|
||||
const pageCount = ref(0)
|
||||
const currentPage = ref({})
|
||||
const answers = ref([])
|
||||
const isFormNotFound = ref(true)
|
||||
const isSent = ref(false)
|
||||
|
||||
async function prepareNewPage() {
|
||||
currentPage.value = data.value.pages[currentPageNumber.value]
|
||||
|
@ -39,62 +46,78 @@ async function submitForm() {
|
|||
await prepareNewPage()
|
||||
} else {
|
||||
await makeAPIRequest(
|
||||
'/answer/create',
|
||||
'POST',
|
||||
{ form_id: 1 },
|
||||
{
|
||||
values: Array.from(Object.keys(answers.value).map((val) => answers.value[val]))
|
||||
}
|
||||
'/answer/create',
|
||||
'POST',
|
||||
{ form_id: Number(route.params.id) },
|
||||
{
|
||||
values: Array.from(Object.keys(answers.value).map((val) => answers.value[val]))
|
||||
}
|
||||
)
|
||||
isSent.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
data.value = await makeAPIRequest('/form/get', 'GET', { id: 1 })
|
||||
const formResponse = await makeAPIRequest('/form/get', 'GET', { id: Number(route.params.id) })
|
||||
if (!formResponse.json || formResponse.status !== 200) {
|
||||
return
|
||||
}
|
||||
data.value = formResponse.json.data
|
||||
pageCount.value = data.value.pages.length
|
||||
isFormNotFound.value = false
|
||||
await prepareNewPage()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h2>{{ data.name }}</h2>
|
||||
<p>{{ currentPage.text }}</p>
|
||||
<FormNotFound v-if="isFormNotFound" />
|
||||
<div v-else>
|
||||
<div v-if="isSent">Форма была успешно отправлена.</div>
|
||||
<div v-else>
|
||||
<h2>{{ data.name }}</h2>
|
||||
<p>{{ currentPage.text }}</p>
|
||||
|
||||
<form @submit.prevent="submitForm">
|
||||
<div class="" v-for="question in currentPage.questions">
|
||||
<h3>{{ question.label }}</h3>
|
||||
<p>{{ question.description }}</p>
|
||||
<TextQuestion
|
||||
v-if="question.question_type === 1"
|
||||
:minLength="question.min_length"
|
||||
:maxLength="question.max_length"
|
||||
:validator="question.validator"
|
||||
:isRequired="question.required"
|
||||
v-model="answers[question.id].value"
|
||||
@input="answers[question.id].value = $event"
|
||||
/>
|
||||
<SelectorQuestion
|
||||
v-if="question.question_type === 2"
|
||||
:minValues="question.min_values"
|
||||
:maxValues="question.max_values"
|
||||
:options="question.options"
|
||||
:isRequired="question.required"
|
||||
v-model="answers[question.id].values"
|
||||
@input="answers[question.id].values = $event"
|
||||
/>
|
||||
<Scale
|
||||
v-if="question.question_type === 3"
|
||||
:min="question.min_value"
|
||||
:max="question.max_value"
|
||||
:minLabel="question.min_label"
|
||||
:maxLabel="question.max_label"
|
||||
:isRequired="question.required"
|
||||
v-model="answers[question.id].value"
|
||||
@input="answers[question.id].value = $event"
|
||||
/>
|
||||
<form @submit.prevent="submitForm">
|
||||
<div class="" v-for="question in currentPage.questions">
|
||||
<h3>{{ question.label }}</h3>
|
||||
<p>{{ question.description }}</p>
|
||||
<TextQuestion
|
||||
v-if="question.question_type === 1"
|
||||
:minLength="question.min_length"
|
||||
:maxLength="question.max_length"
|
||||
:validator="question.validator"
|
||||
:isRequired="question.required"
|
||||
v-model="answers[question.id].value"
|
||||
@input="answers[question.id].value = $event"
|
||||
/>
|
||||
<SelectorQuestion
|
||||
v-if="question.question_type === 2"
|
||||
:minValues="question.min_values"
|
||||
:maxValues="question.max_values"
|
||||
:options="question.options"
|
||||
:isRequired="question.required"
|
||||
v-model="answers[question.id].values"
|
||||
@input="answers[question.id].values = $event"
|
||||
/>
|
||||
<Scale
|
||||
v-if="question.question_type === 3"
|
||||
:min="question.min_value"
|
||||
:max="question.max_value"
|
||||
:minLabel="question.min_label"
|
||||
:maxLabel="question.max_label"
|
||||
:isRequired="question.required"
|
||||
v-model="answers[question.id].value"
|
||||
@input="answers[question.id].value = $event"
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" v-if="currentPageNumber === pageCount - 1">
|
||||
Отправить
|
||||
</button>
|
||||
<button type="submit" v-else>Дальше</button>
|
||||
</form>
|
||||
</div>
|
||||
<button type="submit">Отправить</button>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
Loading…
Reference in a new issue