Newer
Older
gn-synapse / frontend / src / views / DashboardView.vue
<script setup>
// Обзор: состояние сервиса и простое «куда идти дальше» для первого захода.
// Профиль и выход живут в каркасе (App.vue, #footer), heartbeat сессии — тоже
// там; здесь только healthz.
import { onMounted, ref } from "vue";
import { GnLoader, GnMetricCard, GnPageHeader, GnStatusCard } from "gnexus-ui-kit/vue";
import { healthz } from "../api.js";

const health = ref(null);
const loading = ref(true);
const error = ref("");

onMounted(async () => {
  try {
    health.value = await healthz();
  } catch (ex) {
    error.value = `Сервис недоступен: ${ex.message}`;
  } finally {
    loading.value = false;
  }
});
</script>

<template>
  <main class="container page">
    <GnPageHeader kicker="Synapse" title="Обзор" subtitle="Состояние хаба уведомлений" />

    <GnLoader v-if="loading" circle label="Опрашиваю сервис…" />
    <GnStatusCard v-else-if="error" variant="error" icon="ph-warning-circle" :text="error" />

    <template v-else>
      <div class="metrics">
        <GnMetricCard label="Сервис" :value="health.status" icon="ph-broadcast" />
      </div>
      <!-- Навигатор для первого захода: что настроить и в каком порядке -->
      <GnStatusCard
        variant="info"
        icon="ph-info"
        title="С чего начать"
        text="Порядок настройки: Источники — зарегистрировать сервис и выпустить ему API-ключ; Цели — куда доставлять (журнал, сервис через s2s); Правила — какое событие и в какую цель уходит. Доставки покажут, что реально ушло."
      />
    </template>
  </main>
</template>

<style scoped>
/* Максимум 1440 по требованию макета; ниже — обычный поток. */
.page {
  max-width: 1440px;
  margin-inline: auto;
  padding-block: var(--gn-space-6);
  display: flex;
  flex-direction: column;
  gap: var(--gn-space-4);
}
.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--gn-space-4);
}
</style>