AddEditStudentDialog.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <template>
  2. <q-dialog ref="dialogRef" @hide="onDialogHide">
  3. <q-card
  4. class="q-dialog-plugin overflow-hidden"
  5. style="width: 900px; max-width: 95vw"
  6. >
  7. <DefaultDialogHeader title="Cadastro de Aluno" @close="onDialogCancel" />
  8. <q-form ref="formRef" @submit="onOKClick">
  9. <q-card-section class="q-pt-none">
  10. <div class="text-subtitle2 q-mb-sm">Dados do Aluno</div>
  11. <div class="row q-col-gutter-sm">
  12. <DefaultInput
  13. v-model="form.name"
  14. label="Nome do aluno"
  15. class="col-md-5 col-12"
  16. />
  17. <DefaultInputDatePicker
  18. v-model="form.birthdate"
  19. label="Data de Nascimento"
  20. class="col-md-5 col-12"
  21. />
  22. <div class="col-md-2 col-12 flex justify-center items-start">
  23. <div style="position: relative; display: inline-block">
  24. <q-avatar size="72px" color="grey-3">
  25. <img v-if="avatarPreview" :src="avatarPreview" />
  26. <q-icon v-else name="mdi-account" size="42px" color="grey-6" />
  27. </q-avatar>
  28. <q-btn
  29. round
  30. dense
  31. color="primary"
  32. icon="mdi-camera"
  33. size="xs"
  34. style="position: absolute; bottom: 0; right: 0"
  35. @click="triggerFileInput"
  36. />
  37. <input
  38. ref="fileInputRef"
  39. type="file"
  40. accept="image/*"
  41. style="display: none"
  42. @change="onAvatarChange"
  43. />
  44. </div>
  45. </div>
  46. <DefaultInput
  47. v-model="form.cpf"
  48. label="CPF / CNH"
  49. class="col-md-6 col-12"
  50. />
  51. <DefaultSelect
  52. v-model="form.gender"
  53. label="Gênero"
  54. class="col-md-6 col-12"
  55. emit-value
  56. map-options
  57. :options="genderOptions"
  58. />
  59. <DefaultInput
  60. v-model="form.email"
  61. label="E-mail"
  62. class="col-md-6 col-12"
  63. type="email"
  64. />
  65. <DefaultInput
  66. v-model="form.phone"
  67. label="Celular com DDD"
  68. class="col-md-6 col-12"
  69. />
  70. <DefaultInput
  71. v-model="form.cep"
  72. label="Cep"
  73. class="col-md-3 col-12"
  74. />
  75. <DefaultInput
  76. v-model="form.address"
  77. label="Endereço"
  78. class="col-md-6 col-12"
  79. />
  80. <DefaultInput
  81. v-model="form.address_number"
  82. label="Numero"
  83. class="col-md-3 col-12"
  84. />
  85. <DefaultInput
  86. v-model="form.neighborhood"
  87. label="Bairro"
  88. class="col-md-6 col-12"
  89. />
  90. <DefaultInput
  91. v-model="form.city_state"
  92. label="Cidade / Estado"
  93. class="col-md-6 col-12"
  94. />
  95. <DefaultInput
  96. v-model="form.complement"
  97. label="Complemento"
  98. class="col-md-6 col-12"
  99. />
  100. <DefaultInput
  101. v-model="form.payer"
  102. label="Pagador"
  103. class="col-md-6 col-12"
  104. />
  105. <DefaultSelect
  106. v-model="form.how_found"
  107. label="Como nos conheceu?"
  108. class="col-12"
  109. emit-value
  110. map-options
  111. :options="howFoundOptions"
  112. />
  113. <DefaultInput
  114. v-model="form.notes"
  115. label="Observações"
  116. class="col-12"
  117. type="textarea"
  118. autogrow
  119. />
  120. </div>
  121. </q-card-section>
  122. <q-card-actions align="right">
  123. <q-btn
  124. outline
  125. color="primary"
  126. label="CANCELAR"
  127. @click="onDialogCancel"
  128. />
  129. <q-btn
  130. color="primary"
  131. label="CADASTRAR"
  132. type="submit"
  133. :loading="loading"
  134. />
  135. </q-card-actions>
  136. </q-form>
  137. </q-card>
  138. </q-dialog>
  139. </template>
  140. <script setup>
  141. import { ref, useTemplateRef } from "vue";
  142. import { useDialogPluginComponent } from "quasar";
  143. import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
  144. import DefaultInput from "src/components/defaults/DefaultInput.vue";
  145. import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
  146. import DefaultInputDatePicker from "src/components/defaults/DefaultInputDatePicker.vue";
  147. defineEmits([...useDialogPluginComponent.emits]);
  148. const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
  149. useDialogPluginComponent();
  150. const formRef = useTemplateRef("formRef");
  151. const fileInputRef = useTemplateRef("fileInputRef");
  152. const loading = ref(false);
  153. const avatarPreview = ref(null);
  154. const form = ref({
  155. name: null,
  156. birthdate: null,
  157. cpf: null,
  158. gender: "no_preference",
  159. email: null,
  160. phone: null,
  161. cep: null,
  162. address: null,
  163. address_number: null,
  164. neighborhood: null,
  165. city_state: null,
  166. complement: null,
  167. payer: null,
  168. how_found: null,
  169. notes: null,
  170. });
  171. const genderOptions = ref([
  172. { label: "Prefiro não informar", value: "no_preference" },
  173. { label: "Masculino", value: "male" },
  174. { label: "Feminino", value: "female" },
  175. { label: "Outro", value: "other" },
  176. ]);
  177. const howFoundOptions = ref([
  178. { label: "Indicação", value: "referral" },
  179. { label: "Redes Sociais", value: "social_media" },
  180. { label: "Google", value: "google" },
  181. { label: "Outro", value: "other" },
  182. ]);
  183. function triggerFileInput() {
  184. fileInputRef.value?.click();
  185. }
  186. function onAvatarChange(event) {
  187. const file = event.target.files[0];
  188. if (file) {
  189. avatarPreview.value = URL.createObjectURL(file);
  190. }
  191. }
  192. async function onOKClick() {
  193. loading.value = true;
  194. try {
  195. console.log("Saving student:", form.value);
  196. onDialogOK(true);
  197. } finally {
  198. loading.value = false;
  199. }
  200. }
  201. </script>