| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- <template>
- <q-dialog ref="dialogRef" @hide="onDialogHide">
- <q-card
- class="q-dialog-plugin overflow-hidden"
- style="width: 900px; max-width: 95vw"
- >
- <DefaultDialogHeader title="Cadastro de Aluno" @close="onDialogCancel" />
- <q-form ref="formRef" @submit="onOKClick">
- <q-card-section class="q-pt-none">
- <div class="text-subtitle2 q-mb-sm">Dados do Aluno</div>
- <div class="row q-col-gutter-sm">
- <DefaultInput
- v-model="form.name"
- label="Nome do aluno"
- class="col-md-5 col-12"
- :rules="[inputRules.required]"
- />
- <DefaultInputDatePicker
- v-model="form.birthdate"
- label="Data de Nascimento"
- class="col-md-5 col-12"
- />
- <div class="col-md-2 col-12 flex justify-center items-start">
- <div style="position: relative; display: inline-block">
- <q-avatar size="72px" color="grey-3">
- <img v-if="avatarPreview" :src="avatarPreview" />
- <q-icon
- v-else
- name="mdi-account"
- size="42px"
- color="grey-6"
- />
- </q-avatar>
- <q-btn
- round
- dense
- color="primary"
- icon="mdi-camera"
- size="xs"
- style="position: absolute; bottom: 0; right: 0"
- @click="triggerFileInput"
- />
- <input
- ref="fileInputRef"
- type="file"
- accept="image/*"
- style="display: none"
- @change="onAvatarChange"
- />
- </div>
- </div>
- <DefaultInput
- v-model="form.cpf"
- label="CPF / CNH"
- class="col-md-6 col-12"
- :mask="masks.Brasil.cpf"
- :rules="[inputRules.cpf]"
- />
- <DefaultSelect
- v-model="form.gender"
- label="Gênero"
- class="col-md-6 col-12"
- emit-value
- map-options
- :options="genderOptions"
- />
- <DefaultInput
- v-model="form.email"
- label="E-mail"
- class="col-md-6 col-12"
- type="email"
- :rules="[inputRules.email]"
- />
- <DefaultInput
- v-model="form.phone"
- label="Celular com DDD"
- class="col-md-6 col-12"
- :mask="masks.Brasil.celular"
- />
- <DefaultInput
- v-model="form.cep"
- label="CEP"
- class="col-md-3 col-12"
- :mask="masks.Brasil.cep"
- :rules="[inputRules.cep]"
- />
- <DefaultInput
- v-model="form.address"
- label="Endereço"
- class="col-md-6 col-12"
- />
- <DefaultInput
- v-model="form.address_number"
- label="Número"
- class="col-md-3 col-12"
- />
- <DefaultInput
- v-model="form.neighborhood"
- label="Bairro"
- class="col-md-6 col-12"
- />
- <StateSelect
- v-model="form.state"
- label="Estado"
- class="col-md-6 col-12"
- outlined
- />
- <DefaultInput
- v-model="form.complement"
- label="Complemento"
- class="col-md-6 col-12"
- />
- <DefaultInput
- v-model="form.payer"
- label="Pagador"
- class="col-md-6 col-12"
- />
- <DefaultSelect
- v-model="form.how_found"
- label="Como nos conheceu?"
- class="col-12"
- emit-value
- map-options
- :options="howFoundOptions"
- />
- <DefaultInput
- v-model="form.notes"
- label="Observações"
- class="col-12"
- type="textarea"
- autogrow
- />
- </div>
- </q-card-section>
- <q-card-actions align="right">
- <q-btn
- outline
- color="primary"
- label="CANCELAR"
- @click="onDialogCancel"
- />
- <q-btn
- color="primary"
- label="CADASTRAR"
- type="submit"
- :loading="loading"
- />
- </q-card-actions>
- </q-form>
- </q-card>
- </q-dialog>
- </template>
- <script setup>
- import { ref, useTemplateRef } from "vue";
- import { useDialogPluginComponent } from "quasar";
- import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.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 StateSelect from "src/components/selects/StateSelect.vue";
- import { useInputRules } from "src/composables/useInputRules";
- import { useSubmitHandler } from "src/composables/useSubmitHandler";
- import { createStudent } from "src/api/student";
- import masks from "src/helpers/masks";
- import { formatDateDMYtoYMD } from "src/helpers/utils";
- defineEmits([...useDialogPluginComponent.emits]);
- const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
- useDialogPluginComponent();
- const { inputRules } = useInputRules();
- const formRef = useTemplateRef("formRef");
- const fileInputRef = useTemplateRef("fileInputRef");
- const avatarPreview = 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: null,
- complement: null,
- payer: null,
- how_found: null,
- notes: null,
- });
- const genderOptions = ref([
- { label: "Prefiro não informar", value: "no_preference" },
- { label: "Masculino", value: "male" },
- { label: "Feminino", value: "female" },
- { label: "Outro", value: "other" },
- ]);
- const howFoundOptions = ref([
- { label: "Indicação", value: "referral" },
- { label: "Redes Sociais", value: "social_media" },
- { label: "Google", value: "google" },
- { label: "Outro", value: "other" },
- ]);
- const { loading, execute } = useSubmitHandler({
- formRef,
- onSuccess: () => {
- onDialogOK(true);
- },
- });
- function buildPayload() {
- 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?.value ?? null,
- complement: form.value.complement,
- payer_name: form.value.payer,
- how_did_you_know_us: form.value.how_found,
- notes: form.value.notes,
- };
- }
- function triggerFileInput() {
- fileInputRef.value?.click();
- }
- function onAvatarChange(event) {
- const file = event.target.files[0];
- if (file) {
- avatarPreview.value = URL.createObjectURL(file);
- }
- }
- async function onOKClick() {
- await execute(() => createStudent(buildPayload()));
- }
- </script>
|