Files
AstralRinth/packages/ui/src/components/billing/ServersRegionButton.vue
Cal H. 2aabcf36ee refactor: migrate to common eslint+prettier configs (#4168)
* refactor: migrate to common eslint+prettier configs

* fix: prettier frontend

* feat: config changes

* fix: lint issues

* fix: lint

* fix: type imports

* fix: cyclical import issue

* fix: lockfile

* fix: missing dep

* fix: switch to tabs

* fix: continue switch to tabs

* fix: rustfmt parity

* fix: moderation lint issue

* fix: lint issues

* fix: ui intl

* fix: lint issues

* Revert "fix: rustfmt parity"

This reverts commit cb99d2376c321d813d4b7fc7e2a213bb30a54711.

* feat: revert last rs
2025-08-14 20:48:38 +00:00

93 lines
2.9 KiB
Vue

<script setup lang="ts">
import { SignalIcon, SpinnerIcon } from '@modrinth/assets'
import { getPingLevel } from '@modrinth/utils'
import { useVIntl } from '@vintl/vintl'
import { computed } from 'vue'
import type { ServerRegion } from '../../utils/billing'
import { regionOverrides } from '../../utils/regions'
const { formatMessage } = useVIntl()
const currentRegion = defineModel<string | undefined>({ required: true })
const props = defineProps<{
region: ServerRegion
ping?: number
bestPing?: boolean
outOfStock?: boolean
}>()
const isCurrentRegion = computed(() => currentRegion.value === props.region.shortcode)
const flag = computed(
() =>
regionOverrides[props.region.shortcode]?.flag ??
`https://flagcdn.com/${props.region.country_code}.svg`,
)
const overrideTitle = computed(() => regionOverrides[props.region.shortcode]?.name)
const title = computed(() =>
overrideTitle.value ? formatMessage(overrideTitle.value) : props.region.display_name,
)
const locationSubtitle = computed(() =>
overrideTitle.value ? props.region.display_name : undefined,
)
const pingLevel = computed(() => getPingLevel(props.ping ?? 0))
function setRegion() {
currentRegion.value = props.region.shortcode
}
</script>
<template>
<button
:disabled="outOfStock"
class="rounded-2xl p-4 font-semibold transition-all border-2 border-solid flex flex-col items-center gap-3"
:class="{
'bg-button-bg border-transparent text-primary': !isCurrentRegion,
'bg-brand-highlight border-brand text-contrast': isCurrentRegion,
'opacity-50 cursor-not-allowed': outOfStock,
'hover:text-contrast active:scale-95 hover:brightness-[--hover-brightness] focus-visible:brightness-[--hover-brightness] ':
!outOfStock,
}"
@click="setRegion"
>
<img
v-if="flag"
class="aspect-[16/10] max-w-16 w-full object-cover rounded-md border-1 border-solid"
:class="[
isCurrentRegion ? 'border-brand' : 'border-button-border',
{ 'saturate-[0.25]': outOfStock },
]"
:src="flag"
alt=""
aria-hidden="true"
/>
<span class="flex flex-col gap-1 items-center">
<span class="flex items-center gap-1 flex-wrap justify-center">
{{ title }}
<span v-if="outOfStock" class="text-sm text-secondary">(Out of stock)</span>
</span>
<span class="text-xs flex items-center gap-1 text-secondary font-medium">
<template v-if="locationSubtitle">
<span>
{{ locationSubtitle }}
</span>
<span v-if="ping !== -1"></span>
</template>
<template v-if="ping !== -1">
<SignalIcon
v-if="ping"
aria-hidden="true"
:style="`--_signal-${pingLevel}: ${pingLevel <= 2 ? 'var(--color-red)' : pingLevel <= 4 ? 'var(--color-orange)' : 'var(--color-green)'}`"
stroke-width="3px"
class="shrink-0"
/>
<SpinnerIcon v-else class="animate-spin" />
<template v-if="ping"> {{ ping }}ms </template>
<span v-else> Testing connection... </span>
</template>
</span>
</span>
</button>
</template>