internal/dashboard/frontend/src/components/LiveUpdateButton.vue

<script setup lang="ts">
import { IconBroadcast } from "@tabler/icons-vue";
import { type ConnectionStatus } from "composables/useWebSocket";

const props = defineProps<{
  st: ConnectionStatus;
}>();

const emit = defineEmits<{
  (e: "toggleConnection"): void;
}>();

const statusConfig = {
  open: {
    label: "Live",
    btn: "text-lime-400 border-lime-500 hover:border-lime-400 pl-2.5 hover:bg-lime-950",
    dot: "bg-lime-500",
  },
  connecting: {
    label: "Connecting",
    btn: "text-amber-400 border-amber-500 pl-2.5 hover:border-amber-400 hover:bg-amber-950",
    dot: "bg-amber-500",
  },
  disconnected: {
    label: "Update Live",
    btn: "btn-secondary",
    dot: "bg-stone-500",
  },
};
</script>

<template>
  <button
    class="btn-secondary h-8"
    :class="statusConfig[st].btn"
    @click="emit('toggleConnection')"
  >
    <span
      class="relative flex h-2 w-2"
      v-if="st === 'open' || st === 'connecting'"
    >
      <span
        v-if="st === 'open' || st === 'connecting'"
        class="absolute inline-flex h-full w-full animate-ping rounded-full opacity-75"
        :class="statusConfig[st].dot"
      />
      <span
        class="relative inline-flex h-2 w-2 rounded-full"
        :class="statusConfig[st].dot"
      />
    </span>
    <IconBroadcast v-else />
    <span>{{ statusConfig[st].label }}</span>
  </button>
</template>