|
|
@@ -4,10 +4,19 @@
|
|
|
class="q-dialog-plugin dialog-form-card"
|
|
|
style="width: 100%; max-width: 1100px"
|
|
|
>
|
|
|
- <DefaultDialogHeader title="Cadastrar Aluno" @close="onDialogCancel" />
|
|
|
-
|
|
|
- <DefaultForm ref="formRef" @submit="onOKClick">
|
|
|
- <q-scroll-area ref="scrollAreaRef" class="dialog-form-scroll">
|
|
|
+ <DefaultDialogHeader
|
|
|
+ title="Cadastrar Aluno"
|
|
|
+ @close="onDialogCancel"
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultForm
|
|
|
+ ref="formRef"
|
|
|
+ @submit="onOKClick"
|
|
|
+ >
|
|
|
+ <q-scroll-area
|
|
|
+ ref="scrollAreaRef"
|
|
|
+ class="dialog-form-scroll"
|
|
|
+ >
|
|
|
<q-card-section class="q-pt-sm">
|
|
|
<CustomTabComponent
|
|
|
:active-tab="activeTab"
|
|
|
@@ -16,11 +25,14 @@
|
|
|
@update:active-tab="handleTabChange"
|
|
|
/>
|
|
|
|
|
|
- <div v-show="activeTab === 'student'" ref="studentTabRef">
|
|
|
+ <div
|
|
|
+ v-show="activeTab === 'student'"
|
|
|
+ ref="studentTabRef"
|
|
|
+ >
|
|
|
<q-banner
|
|
|
v-if="validationErrors.registration_draft_token"
|
|
|
- rounded
|
|
|
class="bg-red-1 text-negative q-mb-md"
|
|
|
+ rounded
|
|
|
>
|
|
|
{{ validationErrors.registration_draft_token }}
|
|
|
</q-banner>
|
|
|
@@ -35,153 +47,161 @@
|
|
|
<div class="row q-col-gutter-sm">
|
|
|
<DefaultInput
|
|
|
v-model="form.name"
|
|
|
+ class="col-6"
|
|
|
+ label="Nome do Aluno"
|
|
|
:error="!!validationErrors.name"
|
|
|
:error-message="validationErrors.name"
|
|
|
- label="Nome do Aluno"
|
|
|
- class="col-6"
|
|
|
:rules="[inputRules.required]"
|
|
|
/>
|
|
|
|
|
|
<DefaultInputDatePicker
|
|
|
v-model="form.birthdate"
|
|
|
+ class="col-6"
|
|
|
+ label="Data de Nascimento"
|
|
|
:error="!!validationErrors.birth_date"
|
|
|
:error-message="validationErrors.birth_date"
|
|
|
- label="Data de Nascimento"
|
|
|
- class="col-6"
|
|
|
:rules="[inputRules.required]"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.cpf"
|
|
|
+ class="col-6"
|
|
|
+ label="CPF"
|
|
|
:error="!!validationErrors.document_number"
|
|
|
:error-message="validationErrors.document_number"
|
|
|
- label="CPF"
|
|
|
- class="col-6"
|
|
|
:mask="masks.Brasil.cpf"
|
|
|
:rules="[inputRules.cpf]"
|
|
|
/>
|
|
|
|
|
|
<DefaultSelect
|
|
|
v-model="form.gender"
|
|
|
- :error="!!validationErrors.gender"
|
|
|
- :error-message="validationErrors.gender"
|
|
|
- label="Gênero"
|
|
|
class="col-6"
|
|
|
emit-value
|
|
|
+ label="Gênero"
|
|
|
map-options
|
|
|
+ :error="!!validationErrors.gender"
|
|
|
+ :error-message="validationErrors.gender"
|
|
|
:options="genderOptions"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.email"
|
|
|
- :error="!!validationErrors.email"
|
|
|
- :error-message="validationErrors.email"
|
|
|
- label="E-mail"
|
|
|
class="col-6"
|
|
|
+ label="E-mail"
|
|
|
type="email"
|
|
|
+ :error="!!validationErrors.email"
|
|
|
+ :error-message="validationErrors.email"
|
|
|
:rules="[inputRules.email]"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.phone"
|
|
|
+ class="col-6"
|
|
|
+ label="Celular com DDD"
|
|
|
:error="!!validationErrors.phone"
|
|
|
:error-message="validationErrors.phone"
|
|
|
- label="Celular com DDD"
|
|
|
- class="col-6"
|
|
|
:mask="masks.Brasil.celular"
|
|
|
/>
|
|
|
|
|
|
<DefaultCepInput
|
|
|
v-model="form.cep"
|
|
|
+ class="col-4"
|
|
|
:error="!!validationErrors.postal_code"
|
|
|
:error-message="validationErrors.postal_code"
|
|
|
- class="col-4"
|
|
|
:rules="[inputRules.cep]"
|
|
|
- @rua="(v) => (form.address = v)"
|
|
|
- @bairro="(v) => (form.neighborhood = v)"
|
|
|
- @uf="(v) => stateSelectRef?.selectStateByCode(v)"
|
|
|
- @cidade="(v) => citySelectRef?.selectCityByName(v)"
|
|
|
+ @bairro="(value) => (form.neighborhood = value)"
|
|
|
+ @cidade="
|
|
|
+ (value) =>
|
|
|
+ citySelectRef?.selectCityByName(value)
|
|
|
+ "
|
|
|
+ @rua="(value) => (form.address = value)"
|
|
|
+ @uf="
|
|
|
+ (value) =>
|
|
|
+ stateSelectRef?.selectStateByCode(value)
|
|
|
+ "
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.address"
|
|
|
+ class="col-5"
|
|
|
+ label="Endereço"
|
|
|
:error="!!validationErrors.street"
|
|
|
:error-message="validationErrors.street"
|
|
|
- label="Endereço"
|
|
|
- class="col-5"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.address_number"
|
|
|
+ class="col-3"
|
|
|
+ label="Número"
|
|
|
:error="!!validationErrors.address_number"
|
|
|
:error-message="validationErrors.address_number"
|
|
|
- label="Número"
|
|
|
- class="col-3"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.neighborhood"
|
|
|
+ class="col-4"
|
|
|
+ label="Bairro"
|
|
|
:error="!!validationErrors.neighborhood"
|
|
|
:error-message="validationErrors.neighborhood"
|
|
|
- label="Bairro"
|
|
|
- class="col-4"
|
|
|
/>
|
|
|
|
|
|
<CitySelect
|
|
|
ref="citySelectRef"
|
|
|
v-model="selectedCity"
|
|
|
+ class="col-4"
|
|
|
+ label="Cidade"
|
|
|
:error="!!validationErrors.city_id"
|
|
|
:error-message="validationErrors.city_id"
|
|
|
- label="Cidade"
|
|
|
- class="col-4"
|
|
|
:state="selectedState"
|
|
|
/>
|
|
|
|
|
|
<StateSelect
|
|
|
ref="stateSelectRef"
|
|
|
v-model="selectedState"
|
|
|
+ class="col-4"
|
|
|
+ label="Estado"
|
|
|
:error="!!validationErrors.state_id"
|
|
|
:error-message="validationErrors.state_id"
|
|
|
- label="Estado"
|
|
|
- class="col-4"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.complement"
|
|
|
+ class="col-6"
|
|
|
+ label="Complemento"
|
|
|
:error="!!validationErrors.complement"
|
|
|
:error-message="validationErrors.complement"
|
|
|
- label="Complemento"
|
|
|
- class="col-6"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.payer"
|
|
|
+ class="col-6"
|
|
|
+ label="Pagador"
|
|
|
:error="!!validationErrors.payer_name"
|
|
|
:error-message="validationErrors.payer_name"
|
|
|
- label="Pagador"
|
|
|
- class="col-6"
|
|
|
/>
|
|
|
|
|
|
<DefaultSelect
|
|
|
v-model="form.how_found"
|
|
|
- :error="!!validationErrors.how_did_you_know_us"
|
|
|
- :error-message="validationErrors.how_did_you_know_us"
|
|
|
- label="Como nos conheceu?"
|
|
|
class="col-12"
|
|
|
emit-value
|
|
|
+ label="Como nos conheceu?"
|
|
|
map-options
|
|
|
+ :error="!!validationErrors.how_did_you_know_us"
|
|
|
+ :error-message="
|
|
|
+ validationErrors.how_did_you_know_us
|
|
|
+ "
|
|
|
:options="howFoundOptions"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.notes"
|
|
|
- :error="!!validationErrors.notes"
|
|
|
- :error-message="validationErrors.notes"
|
|
|
- label="Observações"
|
|
|
+ autogrow
|
|
|
class="col-12"
|
|
|
+ label="Observações"
|
|
|
type="textarea"
|
|
|
+ :error="!!validationErrors.notes"
|
|
|
+ :error-message="validationErrors.notes"
|
|
|
:input-style="{ minHeight: '120px' }"
|
|
|
- autogrow
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -191,7 +211,10 @@
|
|
|
v-show="activeTab === 'responsible'"
|
|
|
ref="responsibleTabRef"
|
|
|
>
|
|
|
- <q-banner rounded class="bg-orange-1 text-orange-10 q-mb-md">
|
|
|
+ <q-banner
|
|
|
+ class="bg-orange-1 text-orange-10 q-mb-md"
|
|
|
+ rounded
|
|
|
+ >
|
|
|
O aluno é menor de 18 anos. Cadastre um responsável para
|
|
|
concluir.
|
|
|
</q-banner>
|
|
|
@@ -199,37 +222,51 @@
|
|
|
<div class="row q-col-gutter-sm">
|
|
|
<DefaultInput
|
|
|
v-model="responsibleForm.name"
|
|
|
- :error="!!validationErrors['responsible.name']"
|
|
|
- :error-message="validationErrors['responsible.name']"
|
|
|
- label="Nome"
|
|
|
class="col-6"
|
|
|
+ label="Nome"
|
|
|
+ :error="!!validationErrors['responsible.name']"
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.name']
|
|
|
+ "
|
|
|
:rules="
|
|
|
- activeTab === 'responsible' ? [inputRules.required] : []
|
|
|
+ activeTab === 'responsible'
|
|
|
+ ? [inputRules.required]
|
|
|
+ : []
|
|
|
"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="responsibleForm.degree"
|
|
|
- :error="!!validationErrors['responsible.degree']"
|
|
|
- :error-message="validationErrors['responsible.degree']"
|
|
|
- label="Grau de Parentesco"
|
|
|
class="col-6"
|
|
|
+ label="Grau de Parentesco"
|
|
|
+ :error="!!validationErrors['responsible.degree']"
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.degree']
|
|
|
+ "
|
|
|
+ :rules="responsibleRequiredRules"
|
|
|
/>
|
|
|
|
|
|
<DefaultInputDatePicker
|
|
|
v-model="responsibleForm.birth_date"
|
|
|
- :error="!!validationErrors['responsible.birth_date']"
|
|
|
- :error-message="validationErrors['responsible.birth_date']"
|
|
|
- label="Data de Nascimento"
|
|
|
class="col-4"
|
|
|
+ label="Data de Nascimento"
|
|
|
+ :error="
|
|
|
+ !!validationErrors['responsible.birth_date']
|
|
|
+ "
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.birth_date']
|
|
|
+ "
|
|
|
+ :rules="responsibleRequiredRules"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="responsibleForm.cpf"
|
|
|
- :error="!!validationErrors['responsible.cpf']"
|
|
|
- :error-message="validationErrors['responsible.cpf']"
|
|
|
- label="CPF"
|
|
|
class="col-4"
|
|
|
+ label="CPF"
|
|
|
+ :error="!!validationErrors['responsible.cpf']"
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.cpf']
|
|
|
+ "
|
|
|
:mask="masks.Brasil.cpf"
|
|
|
:rules="
|
|
|
activeTab === 'responsible'
|
|
|
@@ -240,123 +277,192 @@
|
|
|
|
|
|
<DefaultSelect
|
|
|
v-model="responsibleForm.gender"
|
|
|
- :error="!!validationErrors['responsible.gender']"
|
|
|
- :error-message="validationErrors['responsible.gender']"
|
|
|
- label="Gênero"
|
|
|
class="col-4"
|
|
|
emit-value
|
|
|
+ label="Gênero"
|
|
|
map-options
|
|
|
+ :error="!!validationErrors['responsible.gender']"
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.gender']
|
|
|
+ "
|
|
|
:options="genderOptions"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="responsibleForm.email"
|
|
|
- :error="!!validationErrors['responsible.email']"
|
|
|
- :error-message="validationErrors['responsible.email']"
|
|
|
- label="E-mail"
|
|
|
class="col-6"
|
|
|
+ label="E-mail"
|
|
|
type="email"
|
|
|
- :rules="[inputRules.email]"
|
|
|
+ :error="!!validationErrors['responsible.email']"
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.email']
|
|
|
+ "
|
|
|
+ :rules="responsibleEmailRules"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="responsibleForm.phone"
|
|
|
- :error="!!validationErrors['responsible.phone']"
|
|
|
- :error-message="validationErrors['responsible.phone']"
|
|
|
- label="Telefone"
|
|
|
class="col-6"
|
|
|
+ label="Telefone"
|
|
|
+ :error="!!validationErrors['responsible.phone']"
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.phone']
|
|
|
+ "
|
|
|
:mask="masks.Brasil.celular"
|
|
|
+ :rules="responsibleRequiredRules"
|
|
|
/>
|
|
|
|
|
|
<DefaultCepInput
|
|
|
v-model="responsibleForm.postal_code"
|
|
|
- :error="!!validationErrors['responsible.postal_code']"
|
|
|
- :error-message="validationErrors['responsible.postal_code']"
|
|
|
class="col-4"
|
|
|
- :rules="[inputRules.cep]"
|
|
|
- @rua="(v) => (responsibleForm.street = v)"
|
|
|
- @bairro="(v) => (responsibleForm.neighborhood = v)"
|
|
|
- @uf="(v) => responsibleStateSelectRef?.selectStateByCode(v)"
|
|
|
- @cidade="(v) => responsibleCitySelectRef?.selectCityByName(v)"
|
|
|
+ :error="
|
|
|
+ !!validationErrors['responsible.postal_code']
|
|
|
+ "
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.postal_code']
|
|
|
+ "
|
|
|
+ :rules="responsibleCepRules"
|
|
|
+ @bairro="
|
|
|
+ (value) =>
|
|
|
+ (responsibleForm.neighborhood = value)
|
|
|
+ "
|
|
|
+ @cidade="
|
|
|
+ (value) =>
|
|
|
+ responsibleCitySelectRef?.selectCityByName(
|
|
|
+ value,
|
|
|
+ )
|
|
|
+ "
|
|
|
+ @rua="
|
|
|
+ (value) =>
|
|
|
+ (responsibleForm.street = value)
|
|
|
+ "
|
|
|
+ @uf="
|
|
|
+ (value) =>
|
|
|
+ responsibleStateSelectRef?.selectStateByCode(
|
|
|
+ value,
|
|
|
+ )
|
|
|
+ "
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="responsibleForm.street"
|
|
|
- :error="!!validationErrors['responsible.street']"
|
|
|
- :error-message="validationErrors['responsible.street']"
|
|
|
- label="Endereço"
|
|
|
class="col-5"
|
|
|
+ label="Endereço"
|
|
|
+ :error="!!validationErrors['responsible.street']"
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.street']
|
|
|
+ "
|
|
|
+ :rules="responsibleRequiredRules"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="responsibleForm.address_number"
|
|
|
- :error="!!validationErrors['responsible.address_number']"
|
|
|
- :error-message="validationErrors['responsible.address_number']"
|
|
|
- label="Número"
|
|
|
class="col-3"
|
|
|
+ label="Número"
|
|
|
+ :error="
|
|
|
+ !!validationErrors[
|
|
|
+ 'responsible.address_number'
|
|
|
+ ]
|
|
|
+ "
|
|
|
+ :error-message="
|
|
|
+ validationErrors[
|
|
|
+ 'responsible.address_number'
|
|
|
+ ]
|
|
|
+ "
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="responsibleForm.neighborhood"
|
|
|
- :error="!!validationErrors['responsible.neighborhood']"
|
|
|
- :error-message="validationErrors['responsible.neighborhood']"
|
|
|
- label="Bairro"
|
|
|
class="col-4"
|
|
|
+ label="Bairro"
|
|
|
+ :error="
|
|
|
+ !!validationErrors[
|
|
|
+ 'responsible.neighborhood'
|
|
|
+ ]
|
|
|
+ "
|
|
|
+ :error-message="
|
|
|
+ validationErrors[
|
|
|
+ 'responsible.neighborhood'
|
|
|
+ ]
|
|
|
+ "
|
|
|
+ :rules="responsibleRequiredRules"
|
|
|
/>
|
|
|
|
|
|
<CitySelect
|
|
|
ref="responsibleCitySelectRef"
|
|
|
v-model="responsibleSelectedCity"
|
|
|
- :error="!!validationErrors['responsible.city_id']"
|
|
|
- :error-message="validationErrors['responsible.city_id']"
|
|
|
- label="Cidade"
|
|
|
class="col-4"
|
|
|
+ label="Cidade"
|
|
|
+ :error="
|
|
|
+ !!validationErrors['responsible.city_id']
|
|
|
+ "
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.city_id']
|
|
|
+ "
|
|
|
+ :rules="responsibleRequiredRules"
|
|
|
:state="responsibleSelectedState"
|
|
|
/>
|
|
|
|
|
|
<StateSelect
|
|
|
ref="responsibleStateSelectRef"
|
|
|
v-model="responsibleSelectedState"
|
|
|
- :error="!!validationErrors['responsible.state_id']"
|
|
|
- :error-message="validationErrors['responsible.state_id']"
|
|
|
- label="Estado"
|
|
|
class="col-4"
|
|
|
+ label="Estado"
|
|
|
+ :error="
|
|
|
+ !!validationErrors['responsible.state_id']
|
|
|
+ "
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.state_id']
|
|
|
+ "
|
|
|
+ :rules="responsibleRequiredRules"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="responsibleForm.complement"
|
|
|
- :error="!!validationErrors['responsible.complement']"
|
|
|
- :error-message="validationErrors['responsible.complement']"
|
|
|
- label="Complemento"
|
|
|
class="col-12"
|
|
|
+ label="Complemento"
|
|
|
+ :error="
|
|
|
+ !!validationErrors['responsible.complement']
|
|
|
+ "
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.complement']
|
|
|
+ "
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="responsibleForm.notes"
|
|
|
- :error="!!validationErrors['responsible.notes']"
|
|
|
- :error-message="validationErrors['responsible.notes']"
|
|
|
- label="Observações"
|
|
|
+ autogrow
|
|
|
class="col-12"
|
|
|
+ label="Observações"
|
|
|
type="textarea"
|
|
|
+ :error="!!validationErrors['responsible.notes']"
|
|
|
+ :error-message="
|
|
|
+ validationErrors['responsible.notes']
|
|
|
+ "
|
|
|
:input-style="{ minHeight: '120px' }"
|
|
|
- autogrow
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
</q-card-section>
|
|
|
</q-scroll-area>
|
|
|
|
|
|
- <q-card-actions align="right">
|
|
|
+ <q-card-actions
|
|
|
+ align="right"
|
|
|
+ class="q-px-md q-pb-md"
|
|
|
+ >
|
|
|
<q-btn
|
|
|
- outline
|
|
|
color="primary"
|
|
|
- label="CANCELAR"
|
|
|
+ label="Cancelar"
|
|
|
+ no-caps
|
|
|
+ outline
|
|
|
@click="onDialogCancel"
|
|
|
/>
|
|
|
+
|
|
|
<q-btn
|
|
|
color="primary"
|
|
|
- :label="primaryActionLabel"
|
|
|
+ no-caps
|
|
|
type="submit"
|
|
|
+ :label="primaryActionLabel"
|
|
|
:loading="loading"
|
|
|
/>
|
|
|
</q-card-actions>
|
|
|
@@ -366,27 +472,41 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { computed, nextTick, ref, watch, useTemplateRef } from "vue";
|
|
|
+import {
|
|
|
+ computed,
|
|
|
+ nextTick,
|
|
|
+ ref,
|
|
|
+ useTemplateRef,
|
|
|
+ watch,
|
|
|
+} from "vue";
|
|
|
+
|
|
|
+import {
|
|
|
+ createStudent,
|
|
|
+ createStudentRegistrationDraft,
|
|
|
+} from "src/api/student";
|
|
|
+
|
|
|
+import {
|
|
|
+ formatDateDMYtoYMD,
|
|
|
+ isUnderage,
|
|
|
+} from "src/helpers/utils";
|
|
|
+
|
|
|
import { useDialogPluginComponent } from "quasar";
|
|
|
+import { useInputRules } from "src/composables/useInputRules";
|
|
|
+import { useScroll } from "src/composables/useScroll";
|
|
|
+import { useSubmitHandler } from "src/composables/useSubmitHandler";
|
|
|
+
|
|
|
+import masks from "src/helpers/masks";
|
|
|
|
|
|
+import DefaultCepInput from "src/components/defaults/DefaultCepInput.vue";
|
|
|
import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
|
|
|
+import DefaultForm from "src/components/defaults/DefaultForm.vue";
|
|
|
import DefaultInput from "src/components/defaults/DefaultInput.vue";
|
|
|
-import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
|
|
|
import DefaultInputDatePicker from "src/components/defaults/DefaultInputDatePicker.vue";
|
|
|
-import DefaultCepInput from "src/components/defaults/DefaultCepInput.vue";
|
|
|
+import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
|
|
|
+import CitySelect from "src/components/selects/CitySelect.vue";
|
|
|
+import StateSelect from "src/components/selects/StateSelect.vue";
|
|
|
import AvatarImageComponent from "src/components/shared/AvatarImageComponent.vue";
|
|
|
import CustomTabComponent from "src/components/shared/CustomTabComponent.vue";
|
|
|
-import StateSelect from "src/components/selects/StateSelect.vue";
|
|
|
-import CitySelect from "src/components/selects/CitySelect.vue";
|
|
|
-import { useInputRules } from "src/composables/useInputRules";
|
|
|
-import { useScroll } from "src/composables/useScroll";
|
|
|
-import { useSubmitHandler } from "src/composables/useSubmitHandler";
|
|
|
-import {
|
|
|
- createStudent,
|
|
|
- createStudentRegistrationDraft,
|
|
|
-} from "src/api/student";
|
|
|
-import masks from "src/helpers/masks";
|
|
|
-import { formatDateDMYtoYMD, isUnderage } from "src/helpers/utils";
|
|
|
|
|
|
defineEmits([...useDialogPluginComponent.emits]);
|
|
|
|
|
|
@@ -394,130 +514,197 @@ const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
|
|
|
useDialogPluginComponent();
|
|
|
|
|
|
const { inputRules } = useInputRules();
|
|
|
+const { scrollToComponent } = useScroll();
|
|
|
|
|
|
+const citySelectRef = useTemplateRef("citySelectRef");
|
|
|
const formRef = useTemplateRef("formRef");
|
|
|
-const scrollAreaRef = useTemplateRef("scrollAreaRef");
|
|
|
-const studentTabRef = useTemplateRef("studentTabRef");
|
|
|
+
|
|
|
+const responsibleCitySelectRef = useTemplateRef(
|
|
|
+ "responsibleCitySelectRef",
|
|
|
+);
|
|
|
+
|
|
|
+const responsibleStateSelectRef = useTemplateRef(
|
|
|
+ "responsibleStateSelectRef",
|
|
|
+);
|
|
|
+
|
|
|
const responsibleTabRef = useTemplateRef("responsibleTabRef");
|
|
|
+const scrollAreaRef = useTemplateRef("scrollAreaRef");
|
|
|
const stateSelectRef = useTemplateRef("stateSelectRef");
|
|
|
-const citySelectRef = useTemplateRef("citySelectRef");
|
|
|
-const responsibleStateSelectRef = useTemplateRef("responsibleStateSelectRef");
|
|
|
-const responsibleCitySelectRef = useTemplateRef("responsibleCitySelectRef");
|
|
|
-
|
|
|
-const REGISTRATION_DRAFT_TOKEN_STORAGE_KEY =
|
|
|
- "student_registration_draft_token";
|
|
|
+const studentTabRef = useTemplateRef("studentTabRef");
|
|
|
|
|
|
+const activeTab = ref("student");
|
|
|
const avatarFile = ref(null);
|
|
|
-const selectedState = ref(null);
|
|
|
-const selectedCity = ref(null);
|
|
|
-const responsibleSelectedState = ref(null);
|
|
|
+const registrationDraftToken = ref(null);
|
|
|
const responsibleSelectedCity = ref(null);
|
|
|
-const activeTab = ref("student");
|
|
|
-
|
|
|
-const registrationDraftToken = ref(
|
|
|
- localStorage.getItem(REGISTRATION_DRAFT_TOKEN_STORAGE_KEY) || null,
|
|
|
-);
|
|
|
-
|
|
|
-const { scrollToComponent } = useScroll();
|
|
|
+const responsibleSelectedState = ref(null);
|
|
|
+const selectedCity = ref(null);
|
|
|
+const selectedState = ref(null);
|
|
|
|
|
|
const form = ref({
|
|
|
- name: null,
|
|
|
- birthdate: null,
|
|
|
- cpf: null,
|
|
|
- gender: "no_preference",
|
|
|
- email: null,
|
|
|
- phone: null,
|
|
|
- cep: null,
|
|
|
address: null,
|
|
|
address_number: null,
|
|
|
- neighborhood: null,
|
|
|
- state_id: null,
|
|
|
+ birthdate: null,
|
|
|
+ cep: null,
|
|
|
city_id: null,
|
|
|
complement: null,
|
|
|
- payer: null,
|
|
|
+ cpf: null,
|
|
|
+ email: null,
|
|
|
+ gender: "no_preference",
|
|
|
how_found: null,
|
|
|
+ name: null,
|
|
|
+ neighborhood: null,
|
|
|
notes: null,
|
|
|
+ payer: null,
|
|
|
+ phone: null,
|
|
|
+ state_id: null,
|
|
|
});
|
|
|
|
|
|
const responsibleForm = ref({
|
|
|
- name: null,
|
|
|
+ address_number: null,
|
|
|
birth_date: null,
|
|
|
+ city_id: null,
|
|
|
+ complement: null,
|
|
|
cpf: null,
|
|
|
- gender: "no_preference",
|
|
|
degree: null,
|
|
|
email: null,
|
|
|
+ gender: "no_preference",
|
|
|
+ name: null,
|
|
|
+ neighborhood: null,
|
|
|
+ notes: null,
|
|
|
phone: null,
|
|
|
postal_code: null,
|
|
|
- street: null,
|
|
|
- address_number: null,
|
|
|
- neighborhood: null,
|
|
|
- city_id: null,
|
|
|
state_id: null,
|
|
|
- complement: null,
|
|
|
- notes: null,
|
|
|
+ street: null,
|
|
|
});
|
|
|
|
|
|
-const isStudentUnderage = computed(() => isUnderage(form.value.birthdate));
|
|
|
+const isStudentUnderage = computed(() =>
|
|
|
+ isUnderage(form.value.birthdate),
|
|
|
+);
|
|
|
+
|
|
|
+const responsibleCepRules = computed(() =>
|
|
|
+ activeTab.value === "responsible"
|
|
|
+ ? [inputRules.required, inputRules.cep]
|
|
|
+ : [inputRules.cep],
|
|
|
+);
|
|
|
+
|
|
|
+const responsibleEmailRules = computed(() =>
|
|
|
+ activeTab.value === "responsible"
|
|
|
+ ? [inputRules.required, inputRules.email]
|
|
|
+ : [inputRules.email],
|
|
|
+);
|
|
|
+
|
|
|
+const responsibleRequiredRules = computed(() =>
|
|
|
+ activeTab.value === "responsible"
|
|
|
+ ? [inputRules.required]
|
|
|
+ : [],
|
|
|
+);
|
|
|
+
|
|
|
const tabs = computed(() => [
|
|
|
- { name: "student", label: "Dados do Aluno" },
|
|
|
+ {
|
|
|
+ label: "Dados do Aluno",
|
|
|
+ name: "student",
|
|
|
+ },
|
|
|
...(isStudentUnderage.value
|
|
|
- ? [{ name: "responsible", label: "Responsável" }]
|
|
|
+ ? [
|
|
|
+ {
|
|
|
+ label: "Responsável",
|
|
|
+ name: "responsible",
|
|
|
+ },
|
|
|
+ ]
|
|
|
: []),
|
|
|
]);
|
|
|
+
|
|
|
const primaryActionLabel = computed(() =>
|
|
|
- isStudentUnderage.value && activeTab.value === "student"
|
|
|
- ? "PRÓXIMO"
|
|
|
- : "CADASTRAR",
|
|
|
+ isStudentUnderage.value &&
|
|
|
+ activeTab.value === "student"
|
|
|
+ ? "Próximo"
|
|
|
+ : "Cadastrar",
|
|
|
);
|
|
|
|
|
|
-watch(selectedState, (state) => {
|
|
|
- form.value.state_id = state?.value ?? null;
|
|
|
-});
|
|
|
+const genderOptions = [
|
|
|
+ {
|
|
|
+ label: "Prefiro não informar",
|
|
|
+ value: "no_preference",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Masculino",
|
|
|
+ value: "male",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Feminino",
|
|
|
+ value: "female",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Outro",
|
|
|
+ value: "other",
|
|
|
+ },
|
|
|
+];
|
|
|
|
|
|
-watch(selectedCity, (city) => {
|
|
|
- form.value.city_id = city?.value ?? null;
|
|
|
-});
|
|
|
+const howFoundOptions = [
|
|
|
+ {
|
|
|
+ label: "Indicação",
|
|
|
+ value: "referral",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Redes Sociais",
|
|
|
+ value: "social_media",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Google",
|
|
|
+ value: "google",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Outro",
|
|
|
+ value: "other",
|
|
|
+ },
|
|
|
+];
|
|
|
|
|
|
-watch(responsibleSelectedState, (state) => {
|
|
|
- responsibleForm.value.state_id = state?.value ?? null;
|
|
|
-});
|
|
|
+const REGISTRATION_DRAFT_TOKEN_STORAGE_KEY =
|
|
|
+ "student_registration_draft_token";
|
|
|
|
|
|
-watch(responsibleSelectedCity, (city) => {
|
|
|
- responsibleForm.value.city_id = city?.value ?? null;
|
|
|
-});
|
|
|
+localStorage.removeItem(
|
|
|
+ REGISTRATION_DRAFT_TOKEN_STORAGE_KEY,
|
|
|
+);
|
|
|
|
|
|
-watch(isStudentUnderage, (underage) => {
|
|
|
- if (!underage && activeTab.value === "responsible") {
|
|
|
- activeTab.value = "student";
|
|
|
- }
|
|
|
-});
|
|
|
+const scrollToTabError = async (
|
|
|
+ component,
|
|
|
+ container,
|
|
|
+ options,
|
|
|
+) => {
|
|
|
+ const element = component?.$el ?? component;
|
|
|
|
|
|
-const genderOptions = ref([
|
|
|
- { label: "Prefiro não informar", value: "no_preference" },
|
|
|
- { label: "Masculino", value: "male" },
|
|
|
- { label: "Feminino", value: "female" },
|
|
|
- { label: "Outro", value: "other" },
|
|
|
-]);
|
|
|
+ const studentElement =
|
|
|
+ studentTabRef.value?.$el ?? studentTabRef.value;
|
|
|
|
|
|
-const howFoundOptions = ref([
|
|
|
- { label: "Indicação", value: "referral" },
|
|
|
- { label: "Redes Sociais", value: "social_media" },
|
|
|
- { label: "Google", value: "google" },
|
|
|
- { label: "Outro", value: "other" },
|
|
|
-]);
|
|
|
+ const responsibleElement =
|
|
|
+ responsibleTabRef.value?.$el ??
|
|
|
+ responsibleTabRef.value;
|
|
|
+
|
|
|
+ if (studentElement?.contains(element)) {
|
|
|
+ await setActiveTab("student");
|
|
|
+ } else if (responsibleElement?.contains(element)) {
|
|
|
+ await setActiveTab("responsible");
|
|
|
+ }
|
|
|
+
|
|
|
+ return scrollToComponent(
|
|
|
+ component,
|
|
|
+ container,
|
|
|
+ options,
|
|
|
+ );
|
|
|
+};
|
|
|
|
|
|
const {
|
|
|
loading: saving,
|
|
|
validationErrors: submitValidationErrors,
|
|
|
execute: executeSubmit,
|
|
|
} = useSubmitHandler({
|
|
|
- formRef,
|
|
|
containerRef: scrollAreaRef,
|
|
|
- scrollFn: scrollToTabError,
|
|
|
+ formRef,
|
|
|
onSuccess: (student) => {
|
|
|
clearRegistrationDraftToken();
|
|
|
onDialogOK(student);
|
|
|
},
|
|
|
+ scrollFn: scrollToTabError,
|
|
|
});
|
|
|
|
|
|
const {
|
|
|
@@ -525,199 +712,290 @@ const {
|
|
|
validationErrors: draftValidationErrors,
|
|
|
execute: executeDraft,
|
|
|
} = useSubmitHandler({
|
|
|
- formRef,
|
|
|
containerRef: scrollAreaRef,
|
|
|
+ formRef,
|
|
|
scrollFn: scrollToTabError,
|
|
|
});
|
|
|
|
|
|
-const loading = computed(() => saving.value || validatingStudent.value);
|
|
|
+const loading = computed(
|
|
|
+ () => saving.value || validatingStudent.value,
|
|
|
+);
|
|
|
+
|
|
|
const validationErrors = computed(() => ({
|
|
|
...draftValidationErrors.value,
|
|
|
...submitValidationErrors.value,
|
|
|
}));
|
|
|
|
|
|
-watch(validationErrors, (errors) => {
|
|
|
- const fields = Object.keys(errors);
|
|
|
- if (fields.some((field) => !field.startsWith("responsible"))) {
|
|
|
- activeTab.value = "student";
|
|
|
- } else if (fields.some((field) => field.startsWith("responsible"))) {
|
|
|
- activeTab.value = "responsible";
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-function onAvatarChange(file) {
|
|
|
- avatarFile.value = file;
|
|
|
-}
|
|
|
-
|
|
|
-function saveRegistrationDraftToken(token) {
|
|
|
- registrationDraftToken.value = token;
|
|
|
- localStorage.setItem(REGISTRATION_DRAFT_TOKEN_STORAGE_KEY, token);
|
|
|
-}
|
|
|
-
|
|
|
-function clearRegistrationDraftToken() {
|
|
|
- registrationDraftToken.value = null;
|
|
|
- localStorage.removeItem(REGISTRATION_DRAFT_TOKEN_STORAGE_KEY);
|
|
|
-}
|
|
|
-
|
|
|
-async function setActiveTab(tab, resetScroll = false) {
|
|
|
- activeTab.value = tab;
|
|
|
- await nextTick();
|
|
|
-
|
|
|
- if (resetScroll) {
|
|
|
- scrollAreaRef.value?.setScrollPosition("vertical", 0, 0);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-async function scrollToTabError(component, container, options) {
|
|
|
- const element = component?.$el ?? component;
|
|
|
- const studentElement = studentTabRef.value?.$el ?? studentTabRef.value;
|
|
|
- const responsibleElement =
|
|
|
- responsibleTabRef.value?.$el ?? responsibleTabRef.value;
|
|
|
-
|
|
|
- if (studentElement?.contains(element)) {
|
|
|
- await setActiveTab("student");
|
|
|
-
|
|
|
- } else if (responsibleElement?.contains(element)) {
|
|
|
- await setActiveTab("responsible");
|
|
|
- }
|
|
|
-
|
|
|
- return scrollToComponent(component, container, options);
|
|
|
-}
|
|
|
-
|
|
|
-function buildResponsiblePayload() {
|
|
|
- return {
|
|
|
- name: responsibleForm.value.name,
|
|
|
- birth_date: responsibleForm.value.birth_date
|
|
|
- ? formatDateDMYtoYMD(responsibleForm.value.birth_date)
|
|
|
- : null,
|
|
|
- cpf: responsibleForm.value.cpf,
|
|
|
- gender: responsibleForm.value.gender,
|
|
|
- degree: responsibleForm.value.degree,
|
|
|
- email: responsibleForm.value.email || null,
|
|
|
- phone: responsibleForm.value.phone,
|
|
|
- postal_code: responsibleForm.value.postal_code,
|
|
|
- street: responsibleForm.value.street,
|
|
|
- address_number: responsibleForm.value.address_number,
|
|
|
- neighborhood: responsibleForm.value.neighborhood,
|
|
|
- city_id: responsibleForm.value.city_id,
|
|
|
- state_id: responsibleForm.value.state_id,
|
|
|
- complement: responsibleForm.value.complement,
|
|
|
- notes: responsibleForm.value.notes,
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-function appendResponsibleToFormData(formData) {
|
|
|
+const appendResponsibleToFormData = (formData) => {
|
|
|
const responsible = buildResponsiblePayload();
|
|
|
+
|
|
|
Object.entries(responsible).forEach(([field, value]) => {
|
|
|
- formData.append(`responsible[${field}]`, value ?? "");
|
|
|
+ formData.append(
|
|
|
+ `responsible[${field}]`,
|
|
|
+ value ?? "",
|
|
|
+ );
|
|
|
});
|
|
|
-}
|
|
|
-
|
|
|
-function buildStudentPayload() {
|
|
|
- return {
|
|
|
- name: form.value.name,
|
|
|
- birth_date: form.value.birthdate
|
|
|
- ? formatDateDMYtoYMD(form.value.birthdate)
|
|
|
- : null,
|
|
|
- document_number: form.value.cpf,
|
|
|
- gender: form.value.gender,
|
|
|
- email: form.value.email || null,
|
|
|
- phone: form.value.phone,
|
|
|
- postal_code: form.value.cep,
|
|
|
- street: form.value.address,
|
|
|
- address_number: form.value.address_number,
|
|
|
- neighborhood: form.value.neighborhood,
|
|
|
- state_id: form.value.state_id,
|
|
|
- city_id: form.value.city_id,
|
|
|
- complement: form.value.complement,
|
|
|
- payer_name: form.value.payer,
|
|
|
- how_did_you_know_us: form.value.how_found,
|
|
|
- notes: form.value.notes,
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-function buildRegistrationDraftPayload() {
|
|
|
- return {
|
|
|
- name: form.value.name,
|
|
|
- birth_date: form.value.birthdate
|
|
|
- ? formatDateDMYtoYMD(form.value.birthdate)
|
|
|
- : null,
|
|
|
- document_number: form.value.cpf,
|
|
|
- email: form.value.email || null,
|
|
|
- registration_draft_token: registrationDraftToken.value,
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-function appendStudentToFormData(formData) {
|
|
|
+};
|
|
|
+
|
|
|
+const appendStudentToFormData = (formData) => {
|
|
|
const student = buildStudentPayload();
|
|
|
+
|
|
|
Object.entries(student).forEach(([field, value]) => {
|
|
|
formData.append(field, value ?? "");
|
|
|
});
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
-function buildPayload() {
|
|
|
+const buildPayload = () => {
|
|
|
if (isStudentUnderage.value) {
|
|
|
if (avatarFile.value) {
|
|
|
const formData = new FormData();
|
|
|
+
|
|
|
appendStudentToFormData(formData);
|
|
|
+
|
|
|
formData.append(
|
|
|
"registration_draft_token",
|
|
|
registrationDraftToken.value,
|
|
|
);
|
|
|
+
|
|
|
formData.append("avatar", avatarFile.value);
|
|
|
+
|
|
|
appendResponsibleToFormData(formData);
|
|
|
+
|
|
|
return formData;
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
...buildStudentPayload(),
|
|
|
- registration_draft_token: registrationDraftToken.value,
|
|
|
+ registration_draft_token:
|
|
|
+ registrationDraftToken.value,
|
|
|
responsible: buildResponsiblePayload(),
|
|
|
};
|
|
|
}
|
|
|
|
|
|
if (avatarFile.value) {
|
|
|
const formData = new FormData();
|
|
|
+
|
|
|
appendStudentToFormData(formData);
|
|
|
formData.append("avatar", avatarFile.value);
|
|
|
+
|
|
|
return formData;
|
|
|
}
|
|
|
|
|
|
return buildStudentPayload();
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
-async function goToResponsible() {
|
|
|
- if (validatingStudent.value) return;
|
|
|
+const buildRegistrationDraftPayload = () => ({
|
|
|
+ birth_date: form.value.birthdate
|
|
|
+ ? formatDateDMYtoYMD(form.value.birthdate)
|
|
|
+ : null,
|
|
|
|
|
|
- const draft = await executeDraft(() =>
|
|
|
- createStudentRegistrationDraft(buildRegistrationDraftPayload()),
|
|
|
+ document_number: form.value.cpf,
|
|
|
+ email: form.value.email || null,
|
|
|
+ name: form.value.name,
|
|
|
+
|
|
|
+ registration_draft_token:
|
|
|
+ registrationDraftToken.value,
|
|
|
+});
|
|
|
+
|
|
|
+const buildResponsiblePayload = () => ({
|
|
|
+ address_number: responsibleForm.value.address_number,
|
|
|
+
|
|
|
+ birth_date: responsibleForm.value.birth_date
|
|
|
+ ? formatDateDMYtoYMD(
|
|
|
+ responsibleForm.value.birth_date,
|
|
|
+ )
|
|
|
+ : null,
|
|
|
+
|
|
|
+ city_id: responsibleForm.value.city_id,
|
|
|
+ complement: responsibleForm.value.complement,
|
|
|
+ cpf: responsibleForm.value.cpf,
|
|
|
+ degree: responsibleForm.value.degree,
|
|
|
+ email: responsibleForm.value.email || null,
|
|
|
+ gender: responsibleForm.value.gender,
|
|
|
+ name: responsibleForm.value.name,
|
|
|
+ neighborhood: responsibleForm.value.neighborhood,
|
|
|
+ notes: responsibleForm.value.notes,
|
|
|
+ phone: responsibleForm.value.phone,
|
|
|
+ postal_code: responsibleForm.value.postal_code,
|
|
|
+ state_id: responsibleForm.value.state_id,
|
|
|
+ street: responsibleForm.value.street,
|
|
|
+});
|
|
|
+
|
|
|
+const buildStudentPayload = () => ({
|
|
|
+ address_number: form.value.address_number,
|
|
|
+
|
|
|
+ birth_date: form.value.birthdate
|
|
|
+ ? formatDateDMYtoYMD(form.value.birthdate)
|
|
|
+ : null,
|
|
|
+
|
|
|
+ city_id: form.value.city_id,
|
|
|
+ complement: form.value.complement,
|
|
|
+ document_number: form.value.cpf,
|
|
|
+ email: form.value.email || null,
|
|
|
+ gender: form.value.gender,
|
|
|
+ how_did_you_know_us: form.value.how_found,
|
|
|
+ name: form.value.name,
|
|
|
+ neighborhood: form.value.neighborhood,
|
|
|
+ notes: form.value.notes,
|
|
|
+ payer_name: form.value.payer,
|
|
|
+ phone: form.value.phone,
|
|
|
+ postal_code: form.value.cep,
|
|
|
+ state_id: form.value.state_id,
|
|
|
+ street: form.value.address,
|
|
|
+});
|
|
|
+
|
|
|
+const clearRegistrationDraftToken = () => {
|
|
|
+ registrationDraftToken.value = null;
|
|
|
+
|
|
|
+ localStorage.removeItem(
|
|
|
+ REGISTRATION_DRAFT_TOKEN_STORAGE_KEY,
|
|
|
);
|
|
|
+};
|
|
|
+
|
|
|
+const goToResponsible = async () => {
|
|
|
+ if (validatingStudent.value) return;
|
|
|
+
|
|
|
+ const createDraft = () =>
|
|
|
+ createStudentRegistrationDraft(
|
|
|
+ buildRegistrationDraftPayload(),
|
|
|
+ );
|
|
|
+
|
|
|
+ let draft;
|
|
|
+
|
|
|
+ try {
|
|
|
+ draft = await executeDraft(createDraft);
|
|
|
+ } catch (error) {
|
|
|
+ const draftTokenError =
|
|
|
+ draftValidationErrors.value
|
|
|
+ .registration_draft_token;
|
|
|
+
|
|
|
+ if (
|
|
|
+ !draftTokenError ||
|
|
|
+ !registrationDraftToken.value
|
|
|
+ ) {
|
|
|
+ throw error;
|
|
|
+ }
|
|
|
+
|
|
|
+ clearRegistrationDraftToken();
|
|
|
+
|
|
|
+ draft = await executeDraft(createDraft);
|
|
|
+ }
|
|
|
+
|
|
|
const nextToken = draft?.registration_draft_token;
|
|
|
|
|
|
- if (nextToken && nextToken !== registrationDraftToken.value) {
|
|
|
+ if (
|
|
|
+ nextToken &&
|
|
|
+ nextToken !== registrationDraftToken.value
|
|
|
+ ) {
|
|
|
saveRegistrationDraftToken(nextToken);
|
|
|
}
|
|
|
|
|
|
await setActiveTab("responsible", true);
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
-async function handleTabChange(tab) {
|
|
|
+const handleTabChange = async (tab) => {
|
|
|
if (tab === activeTab.value) return;
|
|
|
|
|
|
if (tab === "responsible") {
|
|
|
await goToResponsible();
|
|
|
+
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
await setActiveTab(tab, true);
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
-async function onOKClick() {
|
|
|
- if (isStudentUnderage.value && activeTab.value === "student") {
|
|
|
+const onAvatarChange = (file) => {
|
|
|
+ avatarFile.value = file;
|
|
|
+};
|
|
|
+
|
|
|
+const onOKClick = async () => {
|
|
|
+ if (
|
|
|
+ isStudentUnderage.value &&
|
|
|
+ activeTab.value === "student"
|
|
|
+ ) {
|
|
|
await goToResponsible();
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ await executeSubmit(() =>
|
|
|
+ createStudent(buildPayload()),
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const saveRegistrationDraftToken = (token) => {
|
|
|
+ registrationDraftToken.value = token;
|
|
|
+
|
|
|
+ localStorage.setItem(
|
|
|
+ REGISTRATION_DRAFT_TOKEN_STORAGE_KEY,
|
|
|
+ token,
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const setActiveTab = async (
|
|
|
+ tab,
|
|
|
+ resetScroll = false,
|
|
|
+) => {
|
|
|
+ activeTab.value = tab;
|
|
|
+
|
|
|
+ await nextTick();
|
|
|
+
|
|
|
+ if (resetScroll) {
|
|
|
+ scrollAreaRef.value?.setScrollPosition(
|
|
|
+ "vertical",
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ );
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+watch(selectedState, (state) => {
|
|
|
+ form.value.state_id = state?.value ?? null;
|
|
|
+});
|
|
|
+
|
|
|
+watch(selectedCity, (city) => {
|
|
|
+ form.value.city_id = city?.value ?? null;
|
|
|
+});
|
|
|
+
|
|
|
+watch(responsibleSelectedState, (state) => {
|
|
|
+ responsibleForm.value.state_id =
|
|
|
+ state?.value ?? null;
|
|
|
+});
|
|
|
+
|
|
|
+watch(responsibleSelectedCity, (city) => {
|
|
|
+ responsibleForm.value.city_id =
|
|
|
+ city?.value ?? null;
|
|
|
+});
|
|
|
+
|
|
|
+watch(isStudentUnderage, (underage) => {
|
|
|
+ if (
|
|
|
+ !underage &&
|
|
|
+ activeTab.value === "responsible"
|
|
|
+ ) {
|
|
|
+ activeTab.value = "student";
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+watch(validationErrors, (errors) => {
|
|
|
+ const fields = Object.keys(errors);
|
|
|
+
|
|
|
+ if (
|
|
|
+ fields.some(
|
|
|
+ (field) => !field.startsWith("responsible"),
|
|
|
+ )
|
|
|
+ ) {
|
|
|
+ activeTab.value = "student";
|
|
|
+
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- await executeSubmit(() => createStudent(buildPayload()));
|
|
|
-}
|
|
|
+ if (
|
|
|
+ fields.some((field) =>
|
|
|
+ field.startsWith("responsible"),
|
|
|
+ )
|
|
|
+ ) {
|
|
|
+ activeTab.value = "responsible";
|
|
|
+ }
|
|
|
+});
|
|
|
</script>
|