|
@@ -1,14 +1,33 @@
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { computed } from "vue";
|
|
|
|
|
|
|
+import { computed, ref } from "vue";
|
|
|
import { useRouter } from "vue-router";
|
|
import { useRouter } from "vue-router";
|
|
|
import LayoutSistema from "../../layout/LayoutSistema.vue";
|
|
import LayoutSistema from "../../layout/LayoutSistema.vue";
|
|
|
import BotaoAlterarTema from "../../components/BotaoAlterarTema.vue";
|
|
import BotaoAlterarTema from "../../components/BotaoAlterarTema.vue";
|
|
|
import { useAuth } from "../../composables/useAuth.js";
|
|
import { useAuth } from "../../composables/useAuth.js";
|
|
|
|
|
+import { sincronizarAtendimentos } from "../../api/atendimentos.js";
|
|
|
|
|
|
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
|
const { user } = useAuth();
|
|
const { user } = useAuth();
|
|
|
const isAdmin = computed(() => String(user.value?.Nivel) === "3");
|
|
const isAdmin = computed(() => String(user.value?.Nivel) === "3");
|
|
|
|
|
|
|
|
|
|
+const sincronizando = ref(false);
|
|
|
|
|
+const syncResultado = ref(null);
|
|
|
|
|
+const syncErro = ref("");
|
|
|
|
|
+
|
|
|
|
|
+async function sincronizarAgora() {
|
|
|
|
|
+ if (sincronizando.value) return;
|
|
|
|
|
+ sincronizando.value = true;
|
|
|
|
|
+ syncResultado.value = null;
|
|
|
|
|
+ syncErro.value = "";
|
|
|
|
|
+ try {
|
|
|
|
|
+ syncResultado.value = await sincronizarAtendimentos({ limite: 50 });
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ syncErro.value = err?.message ?? "Falha ao sincronizar";
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ sincronizando.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
function irParaUsuarios() {
|
|
function irParaUsuarios() {
|
|
|
router.push({ name: "usuarios" });
|
|
router.push({ name: "usuarios" });
|
|
|
}
|
|
}
|
|
@@ -86,6 +105,48 @@ function irParaUsuarios() {
|
|
|
</button>
|
|
</button>
|
|
|
</section>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
+ <section v-if="isAdmin">
|
|
|
|
|
+ <div class="mb-3 text-xs font-semibold uppercase tracking-[0.16em] text-gray-500 dark:text-gray-400">
|
|
|
|
|
+ Integrações
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="w-full rounded-2xl border border-gray-200 bg-background/70 p-5 shadow-sm dark:border-gray-700 dark:bg-background/20">
|
|
|
|
|
+ <div class="flex items-center justify-between gap-4">
|
|
|
|
|
+ <div class="flex items-center gap-3">
|
|
|
|
|
+ <div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary dark:bg-primary/20">
|
|
|
|
|
+ <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
|
|
|
|
|
+ <path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <div class="text-sm font-semibold text-gray-900 dark:text-gray-100">Atendimentos do Chatbot</div>
|
|
|
|
|
+ <div class="text-xs text-gray-500 dark:text-gray-400">
|
|
|
|
|
+ Importa os protocolos abertos do ifbot com as mensagens de cada atendimento.
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button
|
|
|
|
|
+ type="button"
|
|
|
|
|
+ class="shrink-0 rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-white shadow-sm hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-60"
|
|
|
|
|
+ :disabled="sincronizando"
|
|
|
|
|
+ @click="sincronizarAgora"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ sincronizando ? "Sincronizando..." : "Sincronizar" }}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div v-if="syncResultado" class="mt-4 rounded-lg bg-green-50 px-4 py-3 text-xs text-green-800 dark:bg-green-900/30 dark:text-green-300">
|
|
|
|
|
+ {{ syncResultado.importados }} de {{ syncResultado.processados }} protocolos importados
|
|
|
|
|
+ ({{ syncResultado.mensagens }} mensagens).
|
|
|
|
|
+ Total de protocolos abertos no chatbot: {{ syncResultado.total }}.
|
|
|
|
|
+ <span v-if="syncResultado.erros?.length"> {{ syncResultado.erros.length }} com erro.</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="syncErro" class="mt-4 rounded-lg bg-red-50 px-4 py-3 text-xs text-red-800 dark:bg-red-900/30 dark:text-red-300">
|
|
|
|
|
+ {{ syncErro }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
<section>
|
|
<section>
|
|
|
<div class="mb-3 text-xs font-semibold uppercase tracking-[0.16em] text-gray-500 dark:text-gray-400">
|
|
<div class="mb-3 text-xs font-semibold uppercase tracking-[0.16em] text-gray-500 dark:text-gray-400">
|
|
|
Aparência
|
|
Aparência
|