فهرست منبع

feat: adiciona dados de unidade basico

ebagabee 2 هفته پیش
والد
کامیت
da6be9f92d
4فایلهای تغییر یافته به همراه275 افزوده شده و 128 حذف شده
  1. 32 0
      src/api/unit.js
  2. 5 1
      src/pages/unit/UnitActionPage.vue
  3. 212 123
      src/pages/unit/tabs/UnitDataTab.vue
  4. 26 4
      src/router/routes/unit.route.js

+ 32 - 0
src/api/unit.js

@@ -0,0 +1,32 @@
+import api from "src/api";
+
+export const getUnits = async () => {
+  const { data } = await api.get("/unit");
+  return data.payload;
+};
+
+export const getUnit = async (id) => {
+  const { data } = await api.get(`/unit/${id}`);
+  return data.payload;
+};
+
+export const createUnit = async (formData) => {
+  const { data } = await api.post("/unit", formData, {
+    headers: { "Content-Type": "multipart/form-data" },
+  });
+  
+  return data.payload;
+};
+
+export const updateUnit = async (id, formData) => {
+  formData.append("_method", "PUT");
+  const { data } = await api.post(`/unit/${id}`, formData, {
+    headers: { "Content-Type": "multipart/form-data" },
+  });
+  return data.payload;
+};
+
+export const deleteUnit = async (id) => {
+  const { data } = await api.delete(`/unit/${id}`);
+  return data;
+};

+ 5 - 1
src/pages/unit/UnitActionPage.vue

@@ -4,7 +4,7 @@
 
     <CustomTabComponent v-model:active-tab="activeTab" :tabs />
 
-    <UnitDataTab v-if="activeTab === 'unit_data'" />
+    <UnitDataTab v-if="activeTab === 'unit_data'" :unit-id="unitId" />
     <PartnersTab v-if="activeTab === 'partners'" />
     <ContractsTab v-if="activeTab === 'contracts'" />
     <FinancialTab v-if="activeTab === 'financial'" />
@@ -23,6 +23,10 @@ import FinancialTab from "src/pages/unit/tabs/FinancialTab.vue";
 import HistoryTab from "src/pages/unit/tabs/HistoryTab.vue";
 import MediasTab from "src/pages/unit/tabs/MediasTab.vue";
 import { ref } from "vue";
+import { useRoute } from "vue-router";
+
+const route = useRoute();
+const unitId = route.params.id ? Number(route.params.id) : null;
 
 const activeTab = ref("unit_data");
 

+ 212 - 123
src/pages/unit/tabs/UnitDataTab.vue

@@ -1,150 +1,239 @@
 <template>
   <div class="q-pa-md">
-    <div class="column justify-center items-center q-mb-lg">
-      <AvatarImageComponent @update:file="onAvatarChange" />
-
-      <div class="row full-width q-mt-md q-col-gutter-sm">
-        <DefaultInput
-          v-model="form.social_reason"
-          label="Razão Social"
-          class="col-12"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.fantasy_name"
-          label="Nome Fantasia"
-          class="col-12"
-          outlined
-        />
-
-        <DefaultInput v-model="form.cnpj" label="CNPJ" class="col-4" outlined />
-
-        <DefaultInput
-          v-model="form.state_registration"
-          label="Inscrição Estadual"
-          class="col-4"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.responsible"
-          label="Responsável"
-          class="col-4"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.address"
-          label="Endereço"
-          class="col-8"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.address_number"
-          label="Número"
-          class="col-4"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.zip_code"
-          label="CEP"
-          class="col-3"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.neighborhood"
-          label="Bairro"
-          class="col-5"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.city_state"
-          label="Cidade / Estado"
-          class="col-4"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.complement"
-          label="Complemento"
-          class="col-12"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.primary_email"
-          label="E-mail Principal"
-          class="col-6"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.secondary_email"
-          label="E-mail Secundário"
-          class="col-6"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.phone"
-          label="Telefone"
-          class="col-6"
-          outlined
-        />
-
-        <DefaultInput
-          v-model="form.cellphone_number"
-          label="Celular"
-          class="col-6"
-          outlined
-        />
-      </div>
+    <q-form ref="formRef">
+      <div class="column justify-center items-center q-mb-lg">
+        <AvatarImageComponent ref="avatarRef" @update:file="onAvatarChange" />
+
+        <div class="row full-width q-mt-md q-col-gutter-sm">
+          <DefaultInput
+            v-model="form.social_reason"
+            label="Razão Social"
+            class="col-12"
+            outlined
+            :rules="[inputRules.required]"
+          />
+
+          <DefaultInput
+            v-model="form.fantasy_name"
+            label="Nome Fantasia"
+            class="col-12"
+            outlined
+            :rules="[inputRules.required]"
+          />
+
+          <DefaultInput
+            v-model="form.cnpj"
+            label="CNPJ"
+            class="col-4"
+            outlined
+            :mask="masks.Brasil.cnpj"
+            :rules="[inputRules.required, inputRules.cnpj]"
+          />
+
+          <DefaultInput
+            v-model="form.state_registration"
+            label="Inscrição Estadual"
+            class="col-4"
+            outlined
+          />
+
+          <DefaultInput
+            v-model="form.name_responsible"
+            label="Responsável"
+            class="col-4"
+            outlined
+            :rules="[inputRules.required]"
+          />
+
+          <DefaultCepInput
+            v-model="form.postal_code"
+            class="col-3"
+            outlined
+            :rules="[inputRules.required]"
+            @rua="form.street = $event"
+            @bairro="form.neighborhood = $event"
+            @uf="stateSelectRef?.selectStateByCode($event)"
+            @cidade="citySelectRef?.selectCityByName($event)"
+          />
 
-      <div class="row justify-end q-mt-md items-end full-width q-px-xs">
-        <div class="row q-gutter-sm">
-          <q-btn label="Cancelar" color="primary" outline />
-          <q-btn label="Salvar" color="primary-2" />
+          <DefaultInput
+            v-model="form.street"
+            label="Endereço"
+            class="col-6"
+            outlined
+            :rules="[inputRules.required]"
+          />
+
+          <DefaultInput
+            v-model="form.address_number"
+            label="Número"
+            class="col-3"
+            outlined
+          />
+
+          <DefaultInput
+            v-model="form.neighborhood"
+            label="Bairro"
+            class="col-4"
+            outlined
+            :rules="[inputRules.required]"
+          />
+
+          <StateSelect
+            ref="stateSelectRef"
+            v-model="selectedState"
+            label="Estado"
+            class="col-4"
+            outlined
+            :rules="[inputRules.required]"
+          />
+
+          <CitySelect
+            ref="citySelectRef"
+            v-model="selectedCity"
+            label="Cidade"
+            class="col-4"
+            outlined
+            :state="selectedState"
+            :rules="[inputRules.required]"
+          />
 
-          <q-btn
-            icon="mdi-paperclip-plus"
-            color="primary-2"
-            style="height: 40px; width: 40px"
+          <DefaultInput
+            v-model="form.complement"
+            label="Complemento"
+            class="col-12"
+            outlined
           />
+
+          <DefaultInput
+            v-model="form.email"
+            label="E-mail Principal"
+            class="col-6"
+            outlined
+            :rules="[inputRules.required, 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"
+            :rules="[inputRules.required]"
+          />
+
+          <DefaultInput
+            v-model="form.cell_number"
+            label="Celular"
+            class="col-6"
+            outlined
+            :mask="masks.Brasil.celular"
+          />
+        </div>
+
+        <div class="row justify-end q-mt-md items-end full-width q-px-xs">
+          <div class="row q-gutter-sm">
+            <q-btn label="Cancelar" color="primary" outline @click="onCancel" />
+            <q-btn
+              label="Salvar"
+              color="primary-2"
+              :loading="loading"
+              @click="onSave"
+            />
+          </div>
         </div>
       </div>
-    </div>
+    </q-form>
   </div>
 </template>
 
 <script setup>
+import { ref, watch } from "vue";
+import { useRouter } from "vue-router";
 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";
 import { useFormUpdateTracker } from "src/composables/useFormUpdateTracker";
+import { useSubmitHandler } from "src/composables/useSubmitHandler";
+import { useInputRules } from "src/composables/useInputRules";
+import { createUnit } from "src/api/unit";
+import masks from "src/helpers/masks";
+
+const props = defineProps({
+  unitId: {
+    type: Number,
+    default: null,
+  },
+});
 
-const { form } = useFormUpdateTracker({
-  social_reason: null,
+const router = useRouter();
+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 { inputRules } = useInputRules();
+
+const { form, getFormAsFormData } = useFormUpdateTracker({
   fantasy_name: null,
+  social_reason: null,
   cnpj: null,
   state_registration: null,
-  address: null,
+  name_responsible: null,
+  street: null,
   address_number: null,
-  zip_code: null,
+  postal_code: null,
   neighborhood: null,
-  city_state: null,
   complement: null,
-  responsible: null,
-  primary_email: null,
+  city_id: null,
+  state_id: null,
+  email: null,
   secondary_email: null,
-  phone: null,
-  cellphone_number: null,
+  phone_number: null,
+  cell_number: null,
+  avatar: null,
+});
+
+watch(selectedState, (state) => {
+  form.state_id = state?.value ?? null;
+});
+
+watch(selectedCity, (city) => {
+  form.city_id = city?.value ?? null;
 });
 
 function onAvatarChange(file) {
-  console.log("Avatar file selected:", file);
+  form.avatar = file;
+}
+
+const { loading, execute } = useSubmitHandler({
+  formRef,
+  onSuccess: () => {
+    router.push({ name: "FranchiseePage" });
+  },
+});
+
+async function onSave() {
+  await execute(() => {
+    const formData = getFormAsFormData();
+    return createUnit(formData);
+  });
+}
+
+function onCancel() {
+  router.push({ name: "FranchiseePage" });
 }
 </script>

+ 26 - 4
src/router/routes/unit.route.js

@@ -9,8 +9,7 @@ export default [
         translate: false,
       },
       requireAuth: true,
-      // TODO: Verificar permissao, fazendo seeder e substituindo
-      requiredPermission: "config.city",
+      requiredPermission: "unit,add",
       breadcrumbs: [
         {
           name: "FranchiseePage",
@@ -18,8 +17,31 @@ export default [
         },
         {
           name: "UnitAddPage",
-          title: "Cadastro de Unidade"
-        }
+          title: "Cadastro de Unidade",
+        },
+      ],
+    },
+  },
+  {
+    path: "/unit/:id/edit",
+    name: "UnitEditPage",
+    component: () => import("pages/unit/UnitActionPage.vue"),
+    meta: {
+      title: {
+        value: "Editar Unidade",
+        translate: false,
+      },
+      requireAuth: true,
+      requiredPermission: "unit,edit",
+      breadcrumbs: [
+        {
+          name: "FranchiseePage",
+          title: "Franqueados",
+        },
+        {
+          name: "UnitEditPage",
+          title: "Editar Unidade",
+        },
       ],
     },
   },