internal/dashboard/frontend/src/components/EventTable/EventSourceInfo.vue

<script setup lang="ts">
import { countries } from "src/countries";
import { type FilterActions, type GeoData, useIPInfoStore } from "src/store";
import { type HoneypotEvent } from "src/types";
import { computed } from "vue";

const props = defineProps<{
  evt: HoneypotEvent;
  filterActions: FilterActions;
  geo?: GeoData;
  isMobile?: boolean;
}>();

const { ipInfoIsLoading } = useIPInfoStore();

const flag = computed(() => {
  if (!props.geo?.country?.iso_code) {
    return { flag: "🌐", title: "Unknown" };
  }
  return {
    flag: countries.get(props.geo.country.iso_code)?.[0],
    title: countries.get(props.geo.country.iso_code)?.[1],
  };
});
</script>

<template>
  <div class="flex flex-col gap-0.5">
    <template
      v-if="filterActions.state.resolve_ips && (geo?.domain || geo?.fqdn)"
    >
      <div class="font-medium">
        <template
          v-if="
            geo.domain &&
            geo.fqdn &&
            geo.domain !== geo.fqdn &&
            geo.fqdn.endsWith(geo.domain)
          "
        >
          <router-link
            :to="`/fqdn/${geo.fqdn}`"
            class="peer"
            :title="`View FQDN ${geo.fqdn} Stats (${evt.remote_addr})`"
          >
            {{ geo.fqdn.slice(0, -geo.domain.length) }}
          </router-link>
          <router-link
            :to="`/domain/${geo.domain}`"
            class="font-semibold"
            :title="`View Domain ${geo.domain} Stats (${evt.remote_addr})`"
          >
            {{ geo.domain }}
          </router-link>
        </template>
        <template v-else>
          <router-link
            v-if="geo.domain"
            :to="`/domain/${geo.domain}`"
            class="font-bold"
            :title="`View Domain ${geo.domain} Stats (${evt.remote_addr})`"
          >
            {{ geo.domain }}
          </router-link>
          <router-link
            v-if="geo.fqdn && geo.fqdn !== geo.domain"
            :to="`/fqdn/${geo.fqdn}`"
            :title="`View FQDN ${geo.fqdn} Stats (${evt.remote_addr})`"
          >
            {{ geo.fqdn }}
          </router-link>
        </template>
        (<router-link
          :to="`/ip/${evt.remote_addr}`"
          :class="{
            'animate-pulse': ipInfoIsLoading(evt.remote_addr!),
          }"
          title="View IP Details"
          >{{ evt.remote_addr }}</router-link
        >)
      </div>
    </template>
    <router-link
      v-else
      :to="`/ip/${evt.remote_addr}`"
      class="inline-flex items-center gap-1 font-medium"
      :class="{
        'animate-pulse': ipInfoIsLoading(evt.remote_addr!),
      }"
      title="View IP Details"
    >
      {{ evt.remote_addr }}
    </router-link>

    <div
      v-if="filterActions.state.resolve_ips && geo"
      class="text-muted text-xs"
    >
      <span v-if="flag?.flag" :title="flag.title"> {{ flag.flag }}&nbsp; </span>
      <span v-if="geo.country?.iso_code">
        <router-link
          v-if="geo.city?.name"
          :to="`/city/${geo.city.name}`"
          :title="`View ${geo.city.name} Stats`"
        >
          {{ geo.city.name }},
        </router-link>
        <router-link
          :to="`/country/${geo.country.iso_code}`"
          :title="`View ${countries.get(geo.country.iso_code)?.[1]} Stats`"
        >
          {{ countries.get(geo.country.iso_code)?.[1] }},
        </router-link>
      </span>

      <router-link
        v-if="geo.asn"
        :to="`/asn/${geo.asn.autonomous_system_number}`"
        :title="
          `View ASN ${geo.asn.autonomous_system_number} Stats` +
          (geo.asn.autonomous_system_organization
            ? ` (${geo.asn.autonomous_system_organization})`
            : '')
        "
      >
        <span v-if="geo.asn.autonomous_system_organization">
          {{ geo.asn.autonomous_system_organization }}
        </span>
        <span> (ASN{{ geo.asn.autonomous_system_number }})</span>
      </router-link>
    </div>
  </div>
</template>

<style scoped>
@reference "src/style.css";

a:hover,
.peer:hover + a {
  @apply text-secondary-400;
}
</style>