Parcourir la source

feat: adiciona comentarios em ticket

ebagabee il y a 4 semaines
Parent
commit
edf5519920

+ 16 - 0
src/api/support_reply.js

@@ -0,0 +1,16 @@
+import api from "src/api";
+
+export const getSupportReplies = async (ticketId) => {
+  const { data } = await api.get(`/support-ticket/${ticketId}/replies`);
+  return data.payload;
+};
+
+export const createSupportReply = async (ticketId, payload) => {
+  const { data } = await api.post(`/support-ticket/${ticketId}/replies`, payload);
+  return data.payload;
+};
+
+export const deleteSupportReply = async (ticketId, id) => {
+  const { data } = await api.delete(`/support-ticket/${ticketId}/replies/${id}`);
+  return data;
+};

+ 24 - 33
src/pages/support/components/AddEditTicketDialog.vue

@@ -84,11 +84,11 @@
               </div>
               <div style="max-height: 340px; overflow-y: auto; display: flex; flex-direction: column; gap: 8px;">
                 <TicketCommentCard
-                  v-for="comment in mockComments"
-                  :key="comment.id"
-                  :reply="comment.reply"
-                  :created-at="comment.created_at"
-                  :user-name="comment.user_name"
+                  v-for="reply in replies"
+                  :key="reply.id"
+                  :reply="reply.reply"
+                  :created-at="reply.created_at"
+                  :user-name="reply.user_name"
                 />
               </div>
             </div>
@@ -123,7 +123,7 @@
 </template>
 
 <script setup>
-import { ref, computed } from "vue";
+import { ref, computed, onMounted } from "vue";
 import { useDialogPluginComponent } from "quasar";
 
 import CustomTabComponent from "src/components/shared/CustomTabComponent.vue";
@@ -136,6 +136,8 @@ import { userStore } from "src/stores/user";
 import { useQuasar } from "quasar";
 import { createSupportTicket, updateSupportTicket } from "src/api/support_ticket";
 import CloseTicketDialog from "./CloseTicketDialog.vue";
+import AddReplyDialog from "./AddReplyDialog.vue";
+import { getSupportReplies } from "src/api/support_reply";
 
 defineEmits([...useDialogPluginComponent.emits]);
 
@@ -163,32 +165,12 @@ const tabs = computed(() => {
   return base;
 });
 
-const mockComments = [
-  {
-    id: 1,
-    reply: "Já identifiquei o problema, estou trabalhando na correção.",
-    created_at: "18/05/2026 09:14",
-    user_name: "Ana Souza",
-  },
-  {
-    id: 2,
-    reply: "Correção aplicada em ambiente de homologação, aguardando validação.",
-    created_at: "18/05/2026 11:30",
-    user_name: "Carlos Mendes",
-  },
-  {
-    id: 3,
-    reply: "Validado com sucesso em homologação, subindo para produção.",
-    created_at: "18/05/2026 14:05",
-    user_name: "Ana Souza",
-  },
-  {
-    id: 4,
-    reply: "Deploy concluído. Por favor confirme se o problema foi resolvido.",
-    created_at: "18/05/2026 15:48",
-    user_name: "Carlos Mendes",
-  },
-];
+const replies = ref([]);
+
+const loadReplies = async () => {
+  if (!ticket?.id) return;
+  replies.value = await getSupportReplies(ticket.id);
+};
 
 const priorityOptions = [
   { label: "Alta", value: "alta" },
@@ -220,9 +202,18 @@ const buildPayload = () => ({
 });
 
 const onAddComment = () => {
-  // TODO: implement add comment
+  $q.dialog({
+    component: AddReplyDialog,
+    componentProps: { ticketId: ticket.id },
+  }).onOk(() => {
+    loadReplies();
+  });
 };
 
+onMounted(() => {
+  loadReplies();
+});
+
 const onCloseTicket = () => {
   $q.dialog({
     component: CloseTicketDialog,

+ 69 - 0
src/pages/support/components/AddReplyDialog.vue

@@ -0,0 +1,69 @@
+<template>
+  <q-dialog ref="dialogRef" @hide="onDialogHide">
+    <div style="width: 100%; max-width: 600px">
+      <q-card class="overflow-hidden" style="width: 100%">
+        <DefaultDialogHeader title="Responder Suporte" @close="onDialogCancel" />
+
+        <q-form ref="formRef" @submit="onOKClick">
+          <q-card-section class="q-pt-sm">
+            <DefaultInput
+              v-model="reply"
+              label="Descreva a resposta"
+              type="textarea"
+              class="col-12"
+            />
+          </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="Responder"
+              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 DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
+import DefaultInput from "src/components/defaults/DefaultInput.vue";
+import { createSupportReply } from "src/api/support_reply";
+
+defineEmits([...useDialogPluginComponent.emits]);
+
+const { ticketId } = defineProps({
+  ticketId: {
+    type: Number,
+    required: true,
+  },
+});
+
+const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
+  useDialogPluginComponent();
+
+const loading = ref(false);
+const reply = ref(null);
+
+const onOKClick = async () => {
+  loading.value = true;
+  try {
+    await createSupportReply(ticketId, { reply: reply.value });
+    onDialogOK(true);
+  } finally {
+    loading.value = false;
+  }
+};
+</script>