Quellcode durchsuchen

feat: adiciona dados do contrato

ebagabee vor 1 Monat
Ursprung
Commit
9bfe03a8b4

+ 371 - 0
src/pages/students/components/CreateContractDialog.vue

@@ -0,0 +1,371 @@
+<template>
+  <q-dialog ref="dialogRef" @hide="onDialogHide">
+    <q-card
+      class="q-dialog-plugin overflow-hidden"
+      style="width: 100%; max-width: 1100px"
+    >
+      <DefaultDialogHeader title="Novo Contrato" @close="onDialogCancel" />
+
+      <q-card-section class="q-pt-sm" style="height: 65vh; overflow-y: auto">
+        <div class="text-subtitle1 q-mb-md">Dados do Aluno</div>
+
+        <div class="row q-col-gutter-sm">
+          <div class="col-12">
+            <DefaultInput
+              :model-value="props.student.name"
+              label="Aluno"
+              disable
+            />
+          </div>
+
+          <div class="col-6">
+            <DefaultInput
+              :model-value="props.student.document_number"
+              label="CPF"
+              disable
+            />
+          </div>
+
+          <div class="col-6">
+            <DefaultInput
+              :model-value="formattedBirthDate"
+              label="Data de Nascimento"
+              disable
+            />
+          </div>
+        </div>
+
+        <div class="text-subtitle1 q-mt-lg q-mb-md">Dados do Contrato</div>
+
+        <div class="row q-col-gutter-sm">
+          <div class="col-4">
+            <DefaultInput v-model="form.protocol" label="Protocolo" />
+          </div>
+
+          <div class="col-4">
+            <DefaultInput
+              v-model="form.signature_date"
+              label="Data Assinatura"
+              :mask="masks.Brasil.date"
+            >
+              <template #append>
+                <q-icon name="mdi-calendar" />
+              </template>
+            </DefaultInput>
+          </div>
+
+          <div class="col-4">
+            <DefaultInput
+              v-model="form.end_date"
+              label="Data Encerramento"
+              :mask="masks.Brasil.date"
+            >
+              <template #append>
+                <q-icon name="mdi-calendar" />
+              </template>
+            </DefaultInput>
+          </div>
+
+          <div class="col-5">
+            <DefaultSelect
+              v-model="form.package_id"
+              label="Pacote de Aulas"
+              :options="[]"
+              option-value="id"
+              option-label="name"
+              emit-value
+              map-options
+            />
+          </div>
+
+          <div class="col-7">
+            <DefaultInput
+              v-model="form.class_quantity"
+              label="Qtd. Aulas"
+              type="number"
+            />
+          </div>
+
+          <div class="col-4">
+            <DefaultSelect
+              v-model="form.weekday"
+              label="Dia da Semana"
+              :options="weekdays"
+              option-value="value"
+              option-label="label"
+              emit-value
+              map-options
+            />
+          </div>
+
+          <div class="col-4">
+            <DefaultInput
+              v-model="form.start_time"
+              label="Hora de Início"
+              mask="##:##"
+            >
+              <template #append>
+                <q-icon name="mdi-clock-outline" />
+              </template>
+            </DefaultInput>
+          </div>
+
+          <div class="col-4">
+            <DefaultInput
+              v-model="form.end_time"
+              label="Hora de Término"
+              mask="##:##"
+            >
+              <template #append>
+                <q-icon name="mdi-clock-outline" />
+              </template>
+            </DefaultInput>
+          </div>
+
+          <div class="col-4">
+            <DefaultSelect
+              v-model="form.second_weekday"
+              label="2° Dia da Semana"
+              :options="weekdays"
+              option-value="value"
+              option-label="label"
+              emit-value
+              map-options
+            />
+          </div>
+
+          <div class="col-4">
+            <DefaultInput
+              v-model="form.second_start_time"
+              label="Hora de Início"
+              mask="##:##"
+            >
+              <template #append>
+                <q-icon name="mdi-clock-outline" />
+              </template>
+            </DefaultInput>
+          </div>
+
+          <div class="col-4">
+            <DefaultInput
+              v-model="form.second_end_time"
+              label="Hora de Término"
+              mask="##:##"
+            >
+              <template #append>
+                <q-icon name="mdi-clock-outline" />
+              </template>
+            </DefaultInput>
+          </div>
+        </div>
+
+        <div class="text-subtitle1 q-mt-lg q-mb-md">Dados Financeiros</div>
+
+        <div class="row q-col-gutter-sm">
+          <div class="col-4">
+            <DefaultInput
+              v-model="form.due_date"
+              label="Vencimento"
+              :mask="masks.Brasil.date"
+            >
+              <template #append>
+                <q-icon name="mdi-calendar" />
+              </template>
+            </DefaultInput>
+          </div>
+
+          <div class="col-4">
+            <DefaultInput
+              v-model="form.enrollment_fee"
+              label="Taxa de Matrícula"
+              type="number"
+            />
+          </div>
+
+          <div class="col-4">
+            <DefaultInput
+              v-model="form.total_classes"
+              label="Total de Aulas"
+              type="number"
+            />
+          </div>
+
+          <div class="col-3">
+            <DefaultInput
+              v-model="form.down_payment"
+              label="Entrada"
+              type="number"
+            />
+          </div>
+
+          <div class="col-3">
+            <DefaultSelect
+              v-model="form.installments"
+              label="Parcelas"
+              :options="installmentOptions"
+              option-value="value"
+              option-label="label"
+              emit-value
+              map-options
+            />
+          </div>
+
+          <div class="col-6">
+            <DefaultInput
+              v-model="form.early_payment_discount"
+              label="Desconto até o vencimento (%)"
+              type="number"
+            />
+          </div>
+
+          <div class="col-3">
+            <DefaultInput
+              v-model="form.material_value"
+              label="Valor dos Materiais"
+              type="number"
+            />
+          </div>
+
+          <div class="col-3">
+            <DefaultSelect
+              v-model="form.material_installments"
+              label="Parcelas"
+              :options="installmentOptions"
+              option-value="value"
+              option-label="label"
+              emit-value
+              map-options
+            />
+          </div>
+
+          <div class="col-6">
+            <DefaultInput
+              v-model="form.interest_rate"
+              label="Juros (%) a.m"
+              type="number"
+            />
+          </div>
+
+          <div class="col-6">
+            <DefaultSelect
+              v-model="form.payment_method"
+              label="Forma de Pagamento"
+              :options="paymentMethods"
+              option-value="value"
+              option-label="label"
+              emit-value
+              map-options
+            />
+          </div>
+
+          <div class="col-6">
+            <DefaultInput
+              v-model="form.late_fee"
+              label="Multa (%)"
+              type="number"
+            />
+          </div>
+        </div>
+      </q-card-section>
+
+      <q-separator />
+
+      <q-card-actions align="right">
+        <q-btn
+          outline
+          color="primary"
+          label="CANCELAR"
+          @click="onDialogCancel"
+        />
+        <q-btn
+          color="primary"
+          label="SALVAR"
+          :loading="saving"
+          @click="handleSave"
+        />
+      </q-card-actions>
+    </q-card>
+  </q-dialog>
+</template>
+
+<script setup>
+import { computed } 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 { useSubmitHandler } from "src/composables/useSubmitHandler";
+import { useFormUpdateTracker } from "src/composables/useFormUpdateTracker";
+import { formatDateYMDtoDMY } from "src/helpers/utils";
+import masks from "src/helpers/masks";
+
+const props = defineProps({
+  student: {
+    type: Object,
+    required: true,
+  },
+});
+
+defineEmits([...useDialogPluginComponent.emits]);
+
+const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
+  useDialogPluginComponent();
+
+const { form } = useFormUpdateTracker({
+  protocol: null,
+  signature_date: null,
+  end_date: null,
+  package_id: null,
+  class_quantity: null,
+  weekday: null,
+  start_time: null,
+  end_time: null,
+  second_weekday: null,
+  second_start_time: null,
+  second_end_time: null,
+  due_date: null,
+  enrollment_fee: null,
+  total_classes: null,
+  down_payment: null,
+  installments: null,
+  early_payment_discount: null,
+  material_value: null,
+  material_installments: null,
+  interest_rate: null,
+  payment_method: null,
+  late_fee: null,
+});
+
+const installmentOptions = Array.from({ length: 12 }, (_, i) => ({
+  value: i + 1,
+  label: `${i + 1}x`,
+}));
+
+const paymentMethods = [
+  { value: "pix", label: "Pix" },
+  { value: "credit_card", label: "Cartão de Crédito" },
+  { value: "debit_card", label: "Cartão de Débito" },
+];
+
+const weekdays = [
+  { value: 1, label: "Segunda" },
+  { value: 2, label: "Terça" },
+  { value: 3, label: "Quarta" },
+  { value: 4, label: "Quinta" },
+  { value: 5, label: "Sexta" },
+  { value: 6, label: "Sábado" },
+  { value: 0, label: "Domingo" },
+];
+
+const formattedBirthDate = computed(() =>
+  props.student.birth_date ? formatDateYMDtoDMY(props.student.birth_date) : "",
+);
+
+const { loading: saving } = useSubmitHandler({
+  onSuccess: () => onDialogOK(true),
+});
+
+async function handleSave() {
+  console.log("Save contract", form);
+}
+</script>

+ 2 - 4
src/pages/students/components/EditStudentDialog.vue

@@ -6,7 +6,7 @@
     >
       <DefaultDialogHeader title="Dados do Aluno" @close="onDialogCancel" />
 
-      <q-card-section class="q-pt-sm" style="max-height: 75vh; overflow-y: auto">
+      <q-card-section class="q-pt-sm" style="height: 65vh; overflow-y: auto">
         <CustomTabComponent
           v-model:active-tab="currentTab"
           :tabs="tabs"
@@ -22,7 +22,7 @@
         </div>
 
         <div v-show="currentTab === 'contracts'">
-          <ContractTab />
+          <ContractTab :student="props.student" />
         </div>
 
         <div v-show="currentTab === 'history'">
@@ -44,7 +44,6 @@
           @click="onDialogCancel"
         />
         <q-btn
-          v-if="saveableTabs.includes(currentTab)"
           color="primary"
           label="SALVAR"
           :loading="saving"
@@ -95,7 +94,6 @@ const studentDataTabRef = useTemplateRef("studentDataTabRef");
 const responsibleTabRef = useTemplateRef("responsibleTabRef");
 
 const currentTab = ref("profile");
-const saveableTabs = ["profile", "responsible"];
 
 const { loading: saving, execute } = useSubmitHandler({
   onSuccess: () => onDialogOK(true),

+ 22 - 0
src/pages/students/tabs/ContractTab.vue

@@ -7,6 +7,9 @@
       descricao="contratos"
       :feminino="false"
       no-api-call
+      add-item
+      :show-search-field="false"
+      @on-add-item="handleAdd"
     >
       <template #body-cell-period="{ row }">
         <q-td>{{ row.started_date }} — {{ row.end_date }}</q-td>
@@ -47,10 +50,29 @@
 
 <script setup>
 import { ref } from "vue";
+import { useQuasar } from "quasar";
 import DefaultTable from "src/components/defaults/DefaultTable.vue";
+import CreateContractDialog from "src/pages/students/components/CreateContractDialog.vue";
 
+const props = defineProps({
+  student: {
+    type: Object,
+    required: true,
+  },
+});
+
+const $q = useQuasar();
 const rows = ref([]);
 
+function handleAdd() {
+  $q.dialog({
+    component: CreateContractDialog,
+    componentProps: { student: props.student },
+  }).onOk(() => {
+    console.log("Contract created");
+  });
+}
+
 const columns = ref([
   { name: "contract", label: "Contrato", field: "protocol", align: "left" },
   { name: "period", label: "Data Inicial - Final", field: null, align: "left" },