Răsfoiți Sursa

feat: adiciona funcionalidade de editar e excluir

ebagabee 1 lună în urmă
părinte
comite
b7873bb5b9

+ 20 - 1
src/pages/dashboard/DashboardPage.vue

@@ -164,8 +164,9 @@
                 <div
                   v-for="feriado in feriadosMes"
                   :key="feriado.id"
-                  class="column items-center"
+                  class="column items-center cursor-pointer"
                   style="min-width: 52px"
+                  @click="openEditFromDashboard(feriado)"
                 >
                   <q-badge
                     color="deep-orange"
@@ -198,6 +199,7 @@ import DashboardChartCard from "src/components/charts/DashboardChartCard.vue";
 import GroupedBarChart from "src/components/charts/normal/GroupedBarChart.vue";
 import AniversariantesCard from "src/components/charts/AniversariantesCard.vue";
 import FeriadosDialog from "./components/FeriadosDialog.vue";
+import FeriadosEditDialog from "./components/FeriadosEditDialog.vue";
 import { getHolidays } from "src/api/holiday";
 import { getStudents } from "src/api/student";
 
@@ -355,6 +357,9 @@ const feriadosMes = computed(() => {
       id: h.id,
       dia: new Date(h.holiday_date + "T00:00:00").getDate(),
       nome: h.description,
+      holiday_date: h.holiday_date,
+      description: h.description,
+      type: h.type,
     }));
 });
 
@@ -375,6 +380,20 @@ function openFeriadosDialog() {
   });
 }
 
+function openEditFromDashboard(feriado) {
+  $q.dialog({
+    component: FeriadosEditDialog,
+    componentProps: { holiday: feriado },
+  }).onOk(({ action, holiday: updated, id }) => {
+    if (action === "update") {
+      const idx = allHolidays.value.findIndex((h) => h.id === updated.id);
+      if (idx !== -1) allHolidays.value[idx] = { ...allHolidays.value[idx], ...updated };
+    } else if (action === "delete") {
+      allHolidays.value = allHolidays.value.filter((h) => h.id !== id);
+    }
+  });
+}
+
 onMounted(() => {
   fetchHolidays();
   fetchAlunos();

+ 18 - 28
src/pages/dashboard/components/FeriadosDialog.vue

@@ -92,7 +92,9 @@
               <q-item
                 v-for="holiday in monthHolidays"
                 :key="holiday.id"
-                class="q-pa-sm"
+                class="q-pa-sm cursor-pointer"
+                clickable
+                @click="openEdit(holiday)"
               >
                 <q-item-section avatar>
                   <q-avatar
@@ -113,16 +115,7 @@
                   }}</q-item-label>
                 </q-item-section>
                 <q-item-section side>
-                  <q-btn
-                    flat
-                    round
-                    dense
-                    icon="mdi-trash-can-outline"
-                    color="grey-5"
-                    size="sm"
-                    :loading="deletingId === holiday.id"
-                    @click="removeHoliday(holiday)"
-                  />
+                  <q-icon name="mdi-pencil-outline" color="grey-5" size="xs" />
                 </q-item-section>
               </q-item>
             </q-list>
@@ -206,7 +199,8 @@ import { useDialogPluginComponent, useQuasar } 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 { getHolidays, createHoliday, deleteHoliday } from "src/api/holiday";
+import { getHolidays, createHoliday } from "src/api/holiday";
+import FeriadosEditDialog from "src/pages/dashboard/components/FeriadosEditDialog.vue";
 
 defineEmits([...useDialogPluginComponent.emits]);
 
@@ -225,7 +219,6 @@ const newType = ref("feriado");
 const existingHolidays = ref([]);
 const loadingHolidays = ref(false);
 const saving = ref(false);
-const deletingId = ref(null);
 
 const weekDays = ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"];
 
@@ -357,21 +350,18 @@ async function saveNewRecord() {
   }
 }
 
-async function removeHoliday(holiday) {
-  deletingId.value = holiday.id;
-  try {
-    await deleteHoliday(holiday.id);
-    existingHolidays.value = existingHolidays.value.filter(
-      (h) => h.id !== holiday.id,
-    );
-  } catch {
-    $q.notify({
-      type: "negative",
-      message: "Erro ao remover feriado. Tente novamente.",
-    });
-  } finally {
-    deletingId.value = null;
-  }
+function openEdit(holiday) {
+  $q.dialog({
+    component: FeriadosEditDialog,
+    componentProps: { holiday },
+  }).onOk(({ action, holiday: updated, id }) => {
+    if (action === "update") {
+      const idx = existingHolidays.value.findIndex((h) => h.id === updated.id);
+      if (idx !== -1) existingHolidays.value[idx] = { ...existingHolidays.value[idx], ...updated };
+    } else if (action === "delete") {
+      existingHolidays.value = existingHolidays.value.filter((h) => h.id !== id);
+    }
+  });
 }
 
 async function loadHolidays() {

+ 136 - 0
src/pages/dashboard/components/FeriadosEditDialog.vue

@@ -0,0 +1,136 @@
+<template>
+  <q-dialog ref="dialogRef" @hide="onDialogHide">
+    <q-card class="q-dialog-plugin feriados-edit-dialog">
+      <DefaultDialogHeader :title="dialogTitle" @close="onDialogCancel" />
+
+      <q-card-section class="column q-gutter-md q-pt-sm">
+        <DefaultInput
+          v-model="description"
+          label="Nome do Evento"
+          placeholder="Ex: Ponto facultativo, Natal..."
+          icon="mdi-pencil-outline"
+          outlined
+          autofocus
+        />
+
+        <DefaultSelect
+          v-model="type"
+          label="Selecione o Tipo."
+          :options="typeOptions"
+          emit-value
+          map-options
+          outlined
+        />
+      </q-card-section>
+
+      <q-separator />
+
+      <q-card-actions align="between">
+        <q-btn
+          outline
+          color="negative"
+          label="EXCLUIR"
+          no-caps
+          :loading="deleting"
+          @click="confirmDelete"
+        />
+        <div class="row q-gutter-sm">
+          <q-btn outline color="primary" label="CANCELAR" no-caps @click="onDialogCancel" />
+          <q-btn
+            unelevated
+            color="primary"
+            label="SALVAR"
+            no-caps
+            :disable="!description.trim()"
+            :loading="saving"
+            @click="save"
+          />
+        </div>
+      </q-card-actions>
+    </q-card>
+  </q-dialog>
+</template>
+
+<script setup>
+import { ref, computed } from "vue";
+import { useDialogPluginComponent, useQuasar } 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 { updateHoliday, deleteHoliday } from "src/api/holiday";
+
+defineEmits([...useDialogPluginComponent.emits]);
+
+const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent();
+const $q = useQuasar();
+
+const props = defineProps({
+  holiday: {
+    type: Object,
+    required: true,
+  },
+});
+
+const description = ref(props.holiday.description);
+const type = ref(props.holiday.type ?? "feriado");
+const saving = ref(false);
+const deleting = ref(false);
+
+const typeOptions = [
+  { label: "Feriado", value: "feriado" },
+  { label: "Ponto Facultativo", value: "facultativo" },
+];
+
+const dialogTitle = computed(() => {
+  const [year, month, day] = props.holiday.holiday_date.split("-");
+  return `${day}/${month}/${year}`;
+});
+
+async function save() {
+  const desc = description.value.trim();
+  if (!desc) return;
+
+  saving.value = true;
+  try {
+    const updated = await updateHoliday(
+      { description: desc, holiday_date: props.holiday.holiday_date, type: type.value },
+      props.holiday.id,
+    );
+
+    onDialogOK({
+      action: "update",
+      holiday: { ...props.holiday, description: updated.description, type: updated.type },
+    });
+  } catch {
+    $q.notify({ type: "negative", message: "Erro ao salvar feriado." });
+  } finally {
+    saving.value = false;
+  }
+}
+
+function confirmDelete() {
+  $q.dialog({
+    title: "Excluir feriado",
+    message: `Deseja excluir "${props.holiday.description}"?`,
+    cancel: { label: "Cancelar", flat: true, color: "primary" },
+    ok: { label: "Excluir", unelevated: true, color: "negative" },
+  }).onOk(async () => {
+    deleting.value = true;
+    try {
+      await deleteHoliday(props.holiday.id);
+      onDialogOK({ action: "delete", id: props.holiday.id });
+    } catch {
+      $q.notify({ type: "negative", message: "Erro ao excluir feriado." });
+    } finally {
+      deleting.value = false;
+    }
+  });
+}
+</script>
+
+<style scoped>
+.feriados-edit-dialog {
+  width: 420px;
+  max-width: 95vw;
+}
+</style>