|
|
@@ -1,34 +1,32 @@
|
|
|
<template>
|
|
|
<div>
|
|
|
- <div class="text-h6 q-mb-md">Dados do Responsável</div>
|
|
|
-
|
|
|
<q-form ref="formRef" @submit="onSave">
|
|
|
<div class="row q-col-gutter-sm">
|
|
|
<DefaultInput
|
|
|
- :model-value="String(props.studentId)"
|
|
|
- label="ID do Aluno"
|
|
|
- class="col-md-3 col-12"
|
|
|
- readonly
|
|
|
+ v-model="form.name"
|
|
|
+ label="Nome"
|
|
|
+ class="col-6"
|
|
|
+ :rules="[inputRules.required]"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
- v-model="form.name"
|
|
|
- label="Nome"
|
|
|
- class="col-md-9 col-12"
|
|
|
+ v-model="form.degree"
|
|
|
+ label="Grau de Parentesco"
|
|
|
+ class="col-6"
|
|
|
:rules="[inputRules.required]"
|
|
|
/>
|
|
|
|
|
|
<DefaultInputDatePicker
|
|
|
v-model="form.birth_date"
|
|
|
label="Data de Nascimento"
|
|
|
- class="col-md-4 col-12"
|
|
|
+ class="col-4"
|
|
|
:rules="[inputRules.required]"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.cpf"
|
|
|
label="CPF"
|
|
|
- class="col-md-4 col-12"
|
|
|
+ class="col-4"
|
|
|
:mask="masks.Brasil.cpf"
|
|
|
:rules="[inputRules.required]"
|
|
|
/>
|
|
|
@@ -36,23 +34,16 @@
|
|
|
<DefaultSelect
|
|
|
v-model="form.gender"
|
|
|
label="Gênero"
|
|
|
- class="col-md-4 col-12"
|
|
|
+ class="col-4"
|
|
|
emit-value
|
|
|
map-options
|
|
|
:options="genderOptions"
|
|
|
/>
|
|
|
|
|
|
- <DefaultInput
|
|
|
- v-model="form.degree"
|
|
|
- label="Grau de Parentesco"
|
|
|
- class="col-md-6 col-12"
|
|
|
- :rules="[inputRules.required]"
|
|
|
- />
|
|
|
-
|
|
|
<DefaultInput
|
|
|
v-model="form.email"
|
|
|
label="E-mail"
|
|
|
- class="col-md-6 col-12"
|
|
|
+ class="col-6"
|
|
|
type="email"
|
|
|
:rules="[inputRules.email]"
|
|
|
/>
|
|
|
@@ -60,93 +51,75 @@
|
|
|
<DefaultInput
|
|
|
v-model="form.phone"
|
|
|
label="Telefone"
|
|
|
- class="col-md-6 col-12"
|
|
|
+ class="col-6"
|
|
|
:mask="masks.Brasil.celular"
|
|
|
:rules="[inputRules.required]"
|
|
|
/>
|
|
|
|
|
|
<DefaultCepInput
|
|
|
v-model="form.postal_code"
|
|
|
- class="col-md-6 col-12"
|
|
|
+ class="col-4"
|
|
|
@rua="(v) => (form.street = v)"
|
|
|
@bairro="(v) => (form.neighborhood = v)"
|
|
|
@uf="(v) => stateSelectRef?.selectStateByCode(v)"
|
|
|
+ @cidade="(v) => citySelectRef?.selectCityByName(v)"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.street"
|
|
|
label="Endereço"
|
|
|
- class="col-md-6 col-12"
|
|
|
+ class="col-5"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.address_number"
|
|
|
label="Número"
|
|
|
- class="col-md-6 col-12"
|
|
|
+ class="col-3"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.neighborhood"
|
|
|
label="Bairro"
|
|
|
- class="col-md-6 col-12"
|
|
|
+ class="col-4"
|
|
|
/>
|
|
|
|
|
|
<CitySelect
|
|
|
ref="citySelectRef"
|
|
|
- v-model="form.city"
|
|
|
+ v-model="selectedCity"
|
|
|
label="Cidade"
|
|
|
- class="col-md-6 col-12"
|
|
|
- outlined
|
|
|
- :state="form.state"
|
|
|
- :initial-id="form.city_id ?? null"
|
|
|
+ class="col-4"
|
|
|
+ :state="selectedState"
|
|
|
/>
|
|
|
|
|
|
<StateSelect
|
|
|
ref="stateSelectRef"
|
|
|
- v-model="form.state"
|
|
|
+ v-model="selectedState"
|
|
|
label="Estado"
|
|
|
- class="col-md-6 col-12"
|
|
|
- outlined
|
|
|
- :initial-id="form.state_id ?? null"
|
|
|
+ class="col-4"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.complement"
|
|
|
label="Complemento"
|
|
|
- class="col-md-6 col-12"
|
|
|
+ class="col-12"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
v-model="form.notes"
|
|
|
- label="Observação"
|
|
|
+ label="Observações"
|
|
|
class="col-12"
|
|
|
type="textarea"
|
|
|
+ :input-style="{ minHeight: '120px' }"
|
|
|
autogrow
|
|
|
/>
|
|
|
</div>
|
|
|
|
|
|
- <div class="row justify-end q-mt-md" style="gap: 8px">
|
|
|
- <q-btn
|
|
|
- outline
|
|
|
- color="primary"
|
|
|
- label="Cancelar"
|
|
|
- no-caps
|
|
|
- @click="onCancel"
|
|
|
- />
|
|
|
- <q-btn
|
|
|
- color="primary"
|
|
|
- label="Salvar"
|
|
|
- no-caps
|
|
|
- type="submit"
|
|
|
- :loading="loading"
|
|
|
- />
|
|
|
- </div>
|
|
|
</q-form>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, useTemplateRef, onMounted } from "vue";
|
|
|
+import { ref, watch, onMounted, useTemplateRef } from "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";
|
|
|
@@ -154,12 +127,7 @@ import DefaultCepInput from "src/components/defaults/DefaultCepInput.vue";
|
|
|
import CitySelect from "src/components/selects/CitySelect.vue";
|
|
|
import StateSelect from "src/components/selects/StateSelect.vue";
|
|
|
import { useInputRules } from "src/composables/useInputRules";
|
|
|
-import { useSubmitHandler } from "src/composables/useSubmitHandler";
|
|
|
-import {
|
|
|
- getStudentResponsible,
|
|
|
- createStudentResponsible,
|
|
|
- updateStudentResponsible,
|
|
|
-} from "src/api/studentResponsible";
|
|
|
+import { getStudentResponsible } from "src/api/studentResponsible";
|
|
|
import masks from "src/helpers/masks";
|
|
|
import { formatDateYMDtoDMY, formatDateDMYtoYMD } from "src/helpers/utils";
|
|
|
|
|
|
@@ -175,7 +143,8 @@ const formRef = useTemplateRef("formRef");
|
|
|
const stateSelectRef = useTemplateRef("stateSelectRef");
|
|
|
const citySelectRef = useTemplateRef("citySelectRef");
|
|
|
|
|
|
-const responsibleId = ref(null);
|
|
|
+const selectedState = ref(null);
|
|
|
+const selectedCity = ref(null);
|
|
|
|
|
|
const genderOptions = [
|
|
|
{ label: "Masculino", value: "male" },
|
|
|
@@ -196,28 +165,29 @@ const emptyForm = () => ({
|
|
|
street: null,
|
|
|
address_number: null,
|
|
|
neighborhood: null,
|
|
|
- city: null,
|
|
|
- city_id: null,
|
|
|
- state: null,
|
|
|
state_id: null,
|
|
|
+ city_id: null,
|
|
|
complement: null,
|
|
|
notes: null,
|
|
|
});
|
|
|
|
|
|
const form = ref(emptyForm());
|
|
|
|
|
|
-const { loading, execute } = useSubmitHandler({ formRef });
|
|
|
+watch(selectedState, (state) => {
|
|
|
+ form.value.state_id = state?.value ?? null;
|
|
|
+});
|
|
|
+
|
|
|
+watch(selectedCity, (city) => {
|
|
|
+ form.value.city_id = city?.value ?? null;
|
|
|
+});
|
|
|
|
|
|
async function loadResponsible() {
|
|
|
try {
|
|
|
const data = await getStudentResponsible(props.studentId);
|
|
|
if (data) {
|
|
|
- responsibleId.value = data.id;
|
|
|
form.value = {
|
|
|
name: data.name ?? null,
|
|
|
- birth_date: data.birth_date
|
|
|
- ? formatDateYMDtoDMY(data.birth_date)
|
|
|
- : null,
|
|
|
+ birth_date: data.birth_date ? formatDateYMDtoDMY(data.birth_date) : null,
|
|
|
cpf: data.cpf ?? null,
|
|
|
gender: data.gender ?? "no_preference",
|
|
|
degree: data.degree ?? null,
|
|
|
@@ -227,13 +197,18 @@ async function loadResponsible() {
|
|
|
street: data.street ?? null,
|
|
|
address_number: data.address_number ?? null,
|
|
|
neighborhood: data.neighborhood ?? null,
|
|
|
- city: null,
|
|
|
- city_id: data.city_id ?? null,
|
|
|
- state: null,
|
|
|
state_id: data.state_id ?? null,
|
|
|
+ city_id: data.city_id ?? null,
|
|
|
complement: data.complement ?? null,
|
|
|
notes: data.notes ?? null,
|
|
|
};
|
|
|
+
|
|
|
+ if (data.state_id) {
|
|
|
+ stateSelectRef.value?.selectStateById(data.state_id);
|
|
|
+ }
|
|
|
+ if (data.city_id) {
|
|
|
+ citySelectRef.value?.selectCityById(data.city_id);
|
|
|
+ }
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error("Failed to load responsible:", error);
|
|
|
@@ -242,7 +217,6 @@ async function loadResponsible() {
|
|
|
|
|
|
function buildPayload() {
|
|
|
return {
|
|
|
- student_id: props.studentId,
|
|
|
name: form.value.name,
|
|
|
birth_date: form.value.birth_date
|
|
|
? formatDateDMYtoYMD(form.value.birth_date)
|
|
|
@@ -256,28 +230,17 @@ function buildPayload() {
|
|
|
street: form.value.street,
|
|
|
address_number: form.value.address_number,
|
|
|
neighborhood: form.value.neighborhood,
|
|
|
- city_id: form.value.city?.value ?? form.value.city_id ?? null,
|
|
|
- state_id: form.value.state?.value ?? form.value.state_id ?? null,
|
|
|
+ city_id: form.value.city_id,
|
|
|
+ state_id: form.value.state_id,
|
|
|
complement: form.value.complement,
|
|
|
notes: form.value.notes,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
-async function onSave() {
|
|
|
- await execute(async () => {
|
|
|
- const payload = buildPayload();
|
|
|
- if (responsibleId.value) {
|
|
|
- await updateStudentResponsible(responsibleId.value, payload);
|
|
|
- } else {
|
|
|
- const created = await createStudentResponsible(payload);
|
|
|
- responsibleId.value = created.id;
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-function onCancel() {
|
|
|
- loadResponsible();
|
|
|
-}
|
|
|
-
|
|
|
onMounted(loadResponsible);
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ validate: () => formRef.value?.validate(),
|
|
|
+ buildPayload,
|
|
|
+});
|
|
|
</script>
|