|
|
@@ -0,0 +1,298 @@
|
|
|
+<template>
|
|
|
+ <q-dialog ref="dialogRef" @hide="onDialogHide">
|
|
|
+ <q-card class="q-dialog-plugin overflow-hidden" style="width: 860px; max-width: 95vw">
|
|
|
+ <DefaultDialogHeader :title="() => partner ? 'Editar Sócio' : 'Adicionar Sócio'" @close="onDialogCancel" />
|
|
|
+
|
|
|
+ <q-form ref="formRef" @submit="onOKClick">
|
|
|
+ <q-card-section class="q-pt-none">
|
|
|
+ <div class="column items-center q-mb-md">
|
|
|
+ <AvatarImageComponent ref="avatarRef" @update:file="onAvatarChange" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="row q-col-gutter-sm">
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.name"
|
|
|
+ label="Nome completo"
|
|
|
+ class="col-8"
|
|
|
+ outlined
|
|
|
+ :rules="[inputRules.required]"
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.role"
|
|
|
+ label="Função"
|
|
|
+ class="col-4"
|
|
|
+ outlined
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.social_name"
|
|
|
+ label="Nome social"
|
|
|
+ class="col-6"
|
|
|
+ outlined
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.cpf"
|
|
|
+ label="CPF"
|
|
|
+ class="col-3"
|
|
|
+ outlined
|
|
|
+ :mask="masks.Brasil.cpf"
|
|
|
+ :rules="[inputRules.required]"
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.rg"
|
|
|
+ label="RG"
|
|
|
+ class="col-3"
|
|
|
+ outlined
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="birthDateDisplay"
|
|
|
+ label="Data de Nascimento"
|
|
|
+ class="col-3"
|
|
|
+ outlined
|
|
|
+ :mask="masks.Brasil.date"
|
|
|
+ placeholder="DD/MM/AAAA"
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.participation"
|
|
|
+ label="Participação (%)"
|
|
|
+ class="col-3"
|
|
|
+ outlined
|
|
|
+ type="number"
|
|
|
+ min="0"
|
|
|
+ max="100"
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.email"
|
|
|
+ label="E-mail"
|
|
|
+ class="col-6"
|
|
|
+ outlined
|
|
|
+ :rules="[inputRules.email]"
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.secondary_email"
|
|
|
+ label="E-mail Secundário"
|
|
|
+ class="col-6"
|
|
|
+ outlined
|
|
|
+ :rules="[inputRules.email]"
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.phone_number"
|
|
|
+ label="Telefone"
|
|
|
+ class="col-6"
|
|
|
+ outlined
|
|
|
+ :mask="masks.Brasil.telefone"
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.cell_number"
|
|
|
+ label="Celular"
|
|
|
+ class="col-6"
|
|
|
+ outlined
|
|
|
+ :mask="masks.Brasil.celular"
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultCepInput
|
|
|
+ v-model="form.postal_code"
|
|
|
+ class="col-3"
|
|
|
+ outlined
|
|
|
+ @rua="form.street = $event"
|
|
|
+ @bairro="form.neighborhood = $event"
|
|
|
+ @uf="stateSelectRef?.selectStateByCode($event)"
|
|
|
+ @cidade="citySelectRef?.selectCityByName($event)"
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.street"
|
|
|
+ label="Endereço"
|
|
|
+ class="col-6"
|
|
|
+ outlined
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.address_number"
|
|
|
+ label="Número"
|
|
|
+ class="col-3"
|
|
|
+ outlined
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.neighborhood"
|
|
|
+ label="Bairro"
|
|
|
+ class="col-4"
|
|
|
+ outlined
|
|
|
+ />
|
|
|
+
|
|
|
+ <StateSelect
|
|
|
+ ref="stateSelectRef"
|
|
|
+ v-model="selectedState"
|
|
|
+ label="Estado"
|
|
|
+ class="col-4"
|
|
|
+ outlined
|
|
|
+ />
|
|
|
+
|
|
|
+ <CitySelect
|
|
|
+ ref="citySelectRef"
|
|
|
+ v-model="selectedCity"
|
|
|
+ label="Cidade"
|
|
|
+ class="col-4"
|
|
|
+ outlined
|
|
|
+ :state="selectedState"
|
|
|
+ />
|
|
|
+
|
|
|
+ <DefaultInput
|
|
|
+ v-model="form.complement"
|
|
|
+ label="Complemento"
|
|
|
+ class="col-12"
|
|
|
+ outlined
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </q-card-section>
|
|
|
+
|
|
|
+ <q-card-actions>
|
|
|
+ <q-space />
|
|
|
+ <q-btn outline color="negative" label="Cancelar" @click="onDialogCancel" />
|
|
|
+ <q-btn
|
|
|
+ color="primary-2"
|
|
|
+ :label="partner ? 'Salvar' : 'Adicionar'"
|
|
|
+ type="submit"
|
|
|
+ :loading="loading"
|
|
|
+ />
|
|
|
+ </q-card-actions>
|
|
|
+ </q-form>
|
|
|
+ </q-card>
|
|
|
+ </q-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, watch, onMounted } from "vue";
|
|
|
+import { useDialogPluginComponent } from "quasar";
|
|
|
+import { useInputRules } from "src/composables/useInputRules";
|
|
|
+import { useFormUpdateTracker } from "src/composables/useFormUpdateTracker";
|
|
|
+import { useSubmitHandler } from "src/composables/useSubmitHandler";
|
|
|
+import { createPartner, updatePartner } from "src/api/unit_partner";
|
|
|
+import masks from "src/helpers/masks";
|
|
|
+import { formatDateDMYtoYMD, formatDateYMDtoDMY } from "src/helpers/utils";
|
|
|
+
|
|
|
+import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
|
|
|
+import DefaultInput from "src/components/defaults/DefaultInput.vue";
|
|
|
+import DefaultCepInput from "src/components/defaults/DefaultCepInput.vue";
|
|
|
+import AvatarImageComponent from "src/components/shared/AvatarImageComponent.vue";
|
|
|
+import StateSelect from "src/components/selects/StateSelect.vue";
|
|
|
+import CitySelect from "src/components/selects/CitySelect.vue";
|
|
|
+
|
|
|
+defineEmits([...useDialogPluginComponent.emits]);
|
|
|
+
|
|
|
+const { partner, unitId } = defineProps({
|
|
|
+ partner: {
|
|
|
+ type: Object,
|
|
|
+ default: null,
|
|
|
+ },
|
|
|
+ unitId: {
|
|
|
+ type: Number,
|
|
|
+ required: true,
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const { inputRules } = useInputRules();
|
|
|
+const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent();
|
|
|
+
|
|
|
+const formRef = ref(null);
|
|
|
+const avatarRef = ref(null);
|
|
|
+const stateSelectRef = ref(null);
|
|
|
+const citySelectRef = ref(null);
|
|
|
+
|
|
|
+const selectedState = ref(null);
|
|
|
+const selectedCity = ref(null);
|
|
|
+const avatarChanged = ref(false);
|
|
|
+
|
|
|
+// Exibe DD/MM/YYYY para o usuário; form.birth_date armazena YYYY-MM-DD para o backend
|
|
|
+const birthDateDisplay = ref(
|
|
|
+ partner?.birth_date ? formatDateYMDtoDMY(partner.birth_date) : null,
|
|
|
+);
|
|
|
+
|
|
|
+watch(birthDateDisplay, (val) => {
|
|
|
+ try {
|
|
|
+ form.birth_date = val?.length === 10 ? formatDateDMYtoYMD(val) : null;
|
|
|
+ } catch {
|
|
|
+ form.birth_date = null;
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+const { form, getFormAsFormData } = useFormUpdateTracker({
|
|
|
+ unit_id: unitId,
|
|
|
+ name: partner?.name ?? null,
|
|
|
+ social_name: partner?.social_name ?? null,
|
|
|
+ role: partner?.role ?? null,
|
|
|
+ cpf: partner?.cpf ?? null,
|
|
|
+ rg: partner?.rg ?? null,
|
|
|
+ birth_date: partner?.birth_date ?? null,
|
|
|
+ participation: partner?.participation ?? null,
|
|
|
+ email: partner?.email ?? null,
|
|
|
+ secondary_email: partner?.secondary_email ?? null,
|
|
|
+ phone_number: partner?.phone_number ?? null,
|
|
|
+ cell_number: partner?.cell_number ?? null,
|
|
|
+ postal_code: partner?.postal_code ?? null,
|
|
|
+ street: partner?.street ?? null,
|
|
|
+ address_number: partner?.address_number ?? null,
|
|
|
+ neighborhood: partner?.neighborhood ?? null,
|
|
|
+ complement: partner?.complement ?? null,
|
|
|
+ city_id: partner?.city_id ?? null,
|
|
|
+ state_id: partner?.state_id ?? null,
|
|
|
+});
|
|
|
+
|
|
|
+watch(selectedState, (state) => {
|
|
|
+ form.state_id = state?.value ?? null;
|
|
|
+});
|
|
|
+
|
|
|
+watch(selectedCity, (city) => {
|
|
|
+ form.city_id = city?.value ?? null;
|
|
|
+});
|
|
|
+
|
|
|
+function onAvatarChange(file) {
|
|
|
+ avatarChanged.value = true;
|
|
|
+ form.avatar = file;
|
|
|
+}
|
|
|
+
|
|
|
+const { loading, execute } = useSubmitHandler({
|
|
|
+ formRef,
|
|
|
+ onSuccess: (result) => onDialogOK(result),
|
|
|
+});
|
|
|
+
|
|
|
+async function onOKClick() {
|
|
|
+ await execute(() => {
|
|
|
+ const formData = getFormAsFormData();
|
|
|
+
|
|
|
+ if (avatarChanged.value) {
|
|
|
+ formData.append("avatar", form.avatar ?? "");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (partner) {
|
|
|
+ return updatePartner(partner.id, formData);
|
|
|
+ }
|
|
|
+
|
|
|
+ return createPartner(formData);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ if (!partner) return;
|
|
|
+
|
|
|
+ if (partner.avatar_url) {
|
|
|
+ avatarRef.value?.setImageUrl(partner.avatar_url);
|
|
|
+ }
|
|
|
+ if (partner.state_id) {
|
|
|
+ stateSelectRef.value?.selectStateById(partner.state_id);
|
|
|
+ }
|
|
|
+ if (partner.city_id) {
|
|
|
+ citySelectRef.value?.selectCityById(partner.city_id);
|
|
|
+ }
|
|
|
+});
|
|
|
+</script>
|