Ver código fonte

feat(packages): cria dialog de adicionar/editar pacote

- AddEditPackageDialog com tabs Dados da Unidade e Unidades
- Campos: nome, qtd aulas, matrícula, total contrato, desconto %
- Lista dinâmica de materiais com botão + para adicionar linhas
- PackagesPage abre o dialog via $q.dialog

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ebagabee 1 dia atrás
pai
commit
9b3a369782

+ 5 - 1
src/pages/packages/PackagesPage.vue

@@ -15,9 +15,13 @@
 </template>
 
 <script setup>
+import { useQuasar } from "quasar";
 import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
+import AddEditPackageDialog from "./components/AddEditPackageDialog.vue";
+
+const $q = useQuasar();
 
 const openAddDialog = () => {
-  console.log("Abrir dialog de adicionar pacote");
+  $q.dialog({ component: AddEditPackageDialog });
 };
 </script>

+ 170 - 0
src/pages/packages/components/AddEditPackageDialog.vue

@@ -0,0 +1,170 @@
+<template>
+  <q-dialog ref="dialogRef" @hide="onDialogHide">
+    <div style="width: 100%; max-width: 700px">
+      <p class="text-caption text-white text-uppercase q-mb-sm q-px-xs">
+        Informações Pacote
+      </p>
+
+      <q-card class="overflow-hidden" style="width: 100%">
+        <q-btn
+          flat
+          round
+          dense
+          icon="mdi-close"
+          class="absolute-top-right q-ma-sm"
+          style="z-index: 1"
+          @click="onDialogCancel"
+        />
+
+        <q-form ref="formRef" @submit="onOKClick">
+          <q-card-section class="q-pt-lg">
+            <CustomTabComponent
+              v-model:active-tab="currentTab"
+              :tabs="tabs"
+              class="q-mb-md"
+            />
+
+            <div v-show="currentTab === 'dados'">
+              <div class="row q-col-gutter-sm">
+                <DefaultInput
+                  v-model="form.name"
+                  label="Nome do Pacote"
+                  class="col-12"
+                />
+
+                <DefaultInput
+                  v-model="form.quantity"
+                  label="Quantidade de Aulas"
+                  class="col-12"
+                  type="number"
+                  min="0"
+                />
+
+                <DefaultCurrencyInput
+                  v-model="form.enrollment_fee"
+                  label="R$ Matrícula"
+                  class="col-4"
+                />
+
+                <DefaultCurrencyInput
+                  v-model="form.total_contract"
+                  label="R$ Total do Contrato"
+                  class="col-4"
+                />
+
+                <DefaultInput
+                  v-model="form.discount_percentage"
+                  label="Desconto em %"
+                  class="col-4"
+                  type="number"
+                  min="0"
+                  max="100"
+                />
+
+                <div
+                  v-for="(material, index) in form.materials"
+                  :key="index"
+                  class="col-12"
+                >
+                  <div class="row q-col-gutter-sm items-center">
+                    <DefaultSelect
+                      v-model="material.type"
+                      label="Material"
+                      class="col"
+                      :options="[]"
+                    />
+
+                    <DefaultCurrencyInput
+                      v-model="material.value"
+                      label="R$ 000,00"
+                      class="col-4"
+                    />
+
+                    <div class="col-auto">
+                      <q-btn
+                        v-if="index === form.materials.length - 1"
+                        color="primary"
+                        icon="mdi-plus"
+                        unelevated
+                        style="border-radius: 8px; height: 40px; width: 40px"
+                        @click="addMaterial"
+                      />
+                      <div v-else style="width: 40px" />
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+
+            <div v-show="currentTab === 'unidades'">
+              <!-- Unidades tab content -->
+            </div>
+          </q-card-section>
+
+          <q-card-actions align="right" class="q-px-md q-pb-md">
+            <q-btn
+              outline
+              color="primary"
+              label="Cancelar"
+              @click="onDialogCancel"
+            />
+            <q-btn
+              color="primary"
+              label="Salvar"
+              type="submit"
+              :loading="loading"
+            />
+          </q-card-actions>
+        </q-form>
+      </q-card>
+    </div>
+  </q-dialog>
+</template>
+
+<script setup>
+import { ref } from "vue";
+import { useDialogPluginComponent } from "quasar";
+
+import CustomTabComponent from "src/components/shared/CustomTabComponent.vue";
+import DefaultInput from "src/components/defaults/DefaultInput.vue";
+import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
+import DefaultCurrencyInput from "src/components/defaults/DefaultCurrencyInput.vue";
+
+defineEmits([...useDialogPluginComponent.emits]);
+
+defineProps({
+  package: {
+    type: Object,
+    default: null,
+  },
+});
+
+const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
+  useDialogPluginComponent();
+
+const formRef = ref(null);
+const loading = ref(false);
+const currentTab = ref("dados");
+
+const tabs = [
+  { name: "dados", label: "Dados da Unidade" },
+  { name: "unidades", label: "Unidades" },
+];
+
+const form = ref({
+  name: null,
+  quantity: null,
+  enrollment_fee: null,
+  total_contract: null,
+  discount_percentage: null,
+  materials: [{ type: null, value: null }],
+});
+
+const addMaterial = () => {
+  form.value.materials.push({ type: null, value: null });
+};
+
+const onOKClick = () => {
+  onDialogOK(form.value);
+};
+</script>