Просмотр исходного кода

feat: adiciona interacao em cards

ebagabee 10 часов назад
Родитель
Сommit
4a7e8ebc7b

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

@@ -25,7 +25,7 @@
           :key="pkg.id"
           class="col-12 col-sm-6 col-md-4"
         >
-          <PackageCard :pkg="pkg" />
+          <PackageCard :pkg="pkg" @click="openDetail(pkg)" />
         </div>
 
         <div v-if="packages.length === 0" class="col-12 text-center text-grey-5 q-py-xl">
@@ -38,12 +38,15 @@
 
 <script setup>
 import { ref, onMounted } from "vue";
+import { useQuasar } from "quasar";
 
 import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
 import PackageCard from "./components/PackageCard.vue";
+import PackageDetailDialog from "./components/PackageDetailDialog.vue";
 
 import { getUnitPackages } from "src/api/package";
 
+const $q = useQuasar();
 const loading = ref(false);
 const packages = ref([]);
 
@@ -56,5 +59,9 @@ const fetchPackages = async () => {
   }
 };
 
+const openDetail = (pkg) => {
+  $q.dialog({ component: PackageDetailDialog, componentProps: { pkg } });
+};
+
 onMounted(fetchPackages);
 </script>

+ 257 - 0
src/pages/packages/components/PackageDetailDialog.vue

@@ -0,0 +1,257 @@
+<template>
+  <q-dialog ref="dialogRef" @hide="onDialogHide">
+    <div style="width: 100%; max-width: 700px">
+      <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-card-section class="q-pt-lg">
+          <CustomTabComponent
+            v-model:active-tab="currentTab"
+            :tabs="tabs"
+            class="q-mb-md"
+          />
+
+          <!-- Tab: Dados da Unidade (read-only) -->
+          <div v-show="currentTab === 'dados'">
+            <div class="row q-col-gutter-sm">
+              <q-input
+                :model-value="pkg.name"
+                label="Nome do Pacote"
+                class="col-12"
+                outlined
+                dense
+                readonly
+                label-color="secondary"
+                color="secondary"
+                bg-color="white"
+                style="border-radius: 8px"
+              />
+
+              <q-input
+                :model-value="pkg.quantity_classes + ' Aulas'"
+                label="Quantidade de Aulas"
+                class="col-12"
+                outlined
+                dense
+                readonly
+                label-color="secondary"
+                color="secondary"
+                bg-color="white"
+                style="border-radius: 8px"
+              />
+
+              <q-input
+                :model-value="formatToBRLCurrency(pkg.contract_register_value)"
+                label="R$ Matrícula"
+                class="col-4"
+                outlined
+                dense
+                readonly
+                label-color="secondary"
+                color="secondary"
+                bg-color="white"
+                style="border-radius: 8px"
+              />
+
+              <q-input
+                :model-value="formatToBRLCurrency(pkg.contract_value)"
+                label="R$ Total do Contrato"
+                class="col-4"
+                outlined
+                dense
+                readonly
+                label-color="secondary"
+                color="secondary"
+                bg-color="white"
+                style="border-radius: 8px"
+              />
+
+              <q-input
+                :model-value="pkg.contrat_discount_value ? `D ${pkg.contrat_discount_value}%` : '—'"
+                label="Desconto"
+                class="col-4"
+                outlined
+                dense
+                readonly
+                label-color="secondary"
+                color="secondary"
+                bg-color="white"
+                style="border-radius: 8px"
+              />
+
+              <template v-if="pkg.materials?.length">
+                <div
+                  v-for="material in pkg.materials"
+                  :key="material.product_id"
+                  class="col-12"
+                >
+                  <div class="row q-col-gutter-sm items-center">
+                    <q-input
+                      :model-value="material.name"
+                      label="Material"
+                      class="col"
+                      outlined
+                      dense
+                      readonly
+                      label-color="secondary"
+                      color="secondary"
+                      bg-color="white"
+                      style="border-radius: 8px"
+                    />
+                    <q-input
+                      :model-value="formatToBRLCurrency(material.price)"
+                      label="R$ Unitário"
+                      class="col-3"
+                      outlined
+                      dense
+                      readonly
+                      label-color="secondary"
+                      color="secondary"
+                      bg-color="white"
+                      style="border-radius: 8px"
+                    />
+                  </div>
+                </div>
+              </template>
+            </div>
+          </div>
+
+          <!-- Tab: Neurotrainer/Aula (shell — sem funcionalidade ainda) -->
+          <div v-show="currentTab === 'neurotrainer'">
+            <div class="column q-gutter-y-sm">
+              <div class="row items-center q-gutter-x-sm">
+                <q-input
+                  outlined
+                  dense
+                  label="Buscar Neurotrainer"
+                  label-color="secondary"
+                  color="secondary"
+                  bg-color="white"
+                  class="col"
+                  style="border-radius: 8px"
+                  readonly
+                >
+                  <template #append>
+                    <q-icon name="mdi-magnify" color="secondary" />
+                  </template>
+                </q-input>
+
+                <q-btn
+                  color="primary"
+                  icon="mdi-plus"
+                  unelevated
+                  style="border-radius: 8px; height: 40px; width: 40px; flex-shrink: 0"
+                  disable
+                />
+              </div>
+
+              <div class="row q-col-gutter-sm">
+                <q-input
+                  outlined
+                  dense
+                  label="Dia da Semana"
+                  label-color="secondary"
+                  color="secondary"
+                  bg-color="white"
+                  class="col-4"
+                  style="border-radius: 8px"
+                  readonly
+                />
+                <q-input
+                  outlined
+                  dense
+                  label="Hora de Início"
+                  label-color="secondary"
+                  color="secondary"
+                  bg-color="white"
+                  class="col"
+                  style="border-radius: 8px"
+                  readonly
+                >
+                  <template #append>
+                    <q-icon name="mdi-clock-outline" color="secondary" size="sm" />
+                  </template>
+                </q-input>
+                <q-input
+                  outlined
+                  dense
+                  label="Hora de Término"
+                  label-color="secondary"
+                  color="secondary"
+                  bg-color="white"
+                  class="col"
+                  style="border-radius: 8px"
+                  readonly
+                >
+                  <template #append>
+                    <q-icon name="mdi-clock-outline" color="secondary" size="sm" />
+                  </template>
+                </q-input>
+              </div>
+
+              <!-- Neurotrainer list placeholder -->
+              <div
+                class="rounded-borders q-pa-sm"
+                style="background-color: #f5f5f5; min-height: 120px"
+              >
+                <div class="row items-center q-mb-xs q-px-sm">
+                  <q-icon name="mdi-account-multiple" color="secondary" size="sm" class="q-mr-xs" />
+                  <span class="text-body2">Neurotrainer (0)</span>
+                </div>
+
+                <q-separator class="q-mb-xs" />
+
+                <div class="row q-px-sm q-py-xs">
+                  <span class="col text-caption text-grey-6">Neurotrainer</span>
+                  <span class="col-2 text-caption text-grey-6">Dia</span>
+                  <span class="col-3 text-caption text-grey-6">Horário</span>
+                  <span class="col-auto text-caption text-grey-6">Status</span>
+                </div>
+
+                <q-separator />
+
+                <div class="flex flex-center q-py-md text-grey-5 text-body2">
+                  Nenhum neurotrainer vinculado
+                </div>
+              </div>
+            </div>
+          </div>
+        </q-card-section>
+      </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 { formatToBRLCurrency } from "src/helpers/utils";
+
+defineEmits([...useDialogPluginComponent.emits]);
+
+defineProps({
+  pkg: {
+    type: Object,
+    required: true,
+  },
+});
+
+const { dialogRef, onDialogHide, onDialogCancel } = useDialogPluginComponent();
+
+const currentTab = ref("dados");
+
+const tabs = [
+  { name: "dados", label: "Dados da Unidade" },
+  { name: "neurotrainer", label: "Neurotrainer/Aula" },
+];
+</script>