kodadot/nft-gallery

View on GitHub
components/shared/OnRampModal.vue

Summary

Maintainability
Test Coverage
<template>
  <NeoModal
    :value="isModalActive"
    class="neo-modal"
    data-testid="on-ramp-modal"
    append-to-body
    :no-overlap="noOverlap"
    @close="onClose"
  >
    <ModalBody
      :title="$t('general.chooseProvider')"
      @close="onClose"
    >
      <div>
        <div class="mb-4 flex">
          <NeoCheckbox
            v-model="agreeTos"
            class="self-start pt-1"
          />
          <div>
            {{ $t('fiatOnRamp.agree') }}
            <a
              href="/terms-of-use"
              target="_blank"
              rel="nofollow noopener noreferrer"
              class="text-k-blue hover:text-k-blue-hover"
            >{{ $t('fiatOnRamp.tos') }}</a>
          </div>
        </div>
        <div
          v-for="(provider, index) in providers"
          :key="provider.value"
        >
          <div
            class="provider cursor-pointer flex justify-center items-start flex-col my-4"
            :class="{
              provider__disabled: provider.disabled || !agreeTos,
            }"
            @click="onSelect(provider.value)"
          >
            <div class="flex justify-center">
              <img
                :alt="`${provider.value} provider logo`"
                :src="provider.image"
                class="provider-logo"
              >
              <p
                v-if="provider.disabled"
                class="ml-2 text-xs text-k-grey"
              >
                {{ $t('soon') }}
              </p>
            </div>

            <div class="mt-4 flex items-center justify-between w-full">
              <div class="text-xs text-k-grey">
                {{ $t('general.supports') }}
              </div>

              <div class="text-xs text-k-grey">
                {{ getSupportedTokensToText(provider.supports[vm]) }}
              </div>
            </div>
          </div>

          <hr
            v-if="index !== providers.length - 1"
            class="my-0"
          >
        </div>
      </div>
    </ModalBody>
  </NeoModal>
</template>

<script setup lang="ts">
import { NeoCheckbox, NeoModal } from '@kodadot1/brick'
import type { ChainVM } from '@kodadot1/static'
import ModalBody from '@/components/shared/modals/ModalBody.vue'

enum Provider {
  TRANSAK,
  RAMP,
}

const emit = defineEmits(['close'])
const props = defineProps<{
  modelValue: boolean
  noOverlap?: boolean
}>()

const { accountId } = useAuth()
const { $i18n } = useNuxtApp()

const isModalActive = useVModel(props, 'modelValue')
const agreeTos = ref<boolean>(false)

const { vm } = useChain()
const { init: initTransak } = useTransak()
const { init: initRamp } = useRamp()

const { isDarkMode } = useTheme()

const getImage = (service: string) => {
  return `/onramp-providers/${service}-logo${
    isDarkMode.value ? '-dark' : ''
  }.svg`
}

const getSupportedTokensToText = (tokens: string[]) =>
  tokens.map(token => `$${token}`).join(', ')

const PROVIDER_TOKEN_SUPPORTS = {
  SUB: ['DOT', 'KSM'],
  EVM: ['ETH'],
}

const providers = computed<{ image: string, disabled: boolean, supports: Record<ChainVM, string[]>, value: Provider }[]>(() => [
  {
    image: getImage('transak'),
    disabled: false,
    supports: PROVIDER_TOKEN_SUPPORTS,
    value: Provider.TRANSAK,
  },
  {
    image: getImage('ramp'),
    disabled: false,
    supports: PROVIDER_TOKEN_SUPPORTS,
    value: Provider.RAMP,
  },
])

const onClose = () => {
  emit('close')
}

const onSelect = (provider: Provider) => {
  const selectedProvider = providers.value.find(p => p.value === provider)

  if (selectedProvider?.disabled || !agreeTos.value) {
    return
  }

  onClose()

  switch (selectedProvider?.value) {
    case Provider.TRANSAK:
      transakInit()
      break
    case Provider.RAMP:
      rampInit()
      break
    default:
      break
  }
}

const rampInit = () => {
  initRamp({
    address: accountId.value,
    onSuccess,
  })
}

const transakInit = () => {
  initTransak({
    address: accountId.value,
    onSuccess,
  })
}

const onSuccess = () => {
  successMessage($i18n.t('general.successfullyAddedFunds'))
}
</script>

<style lang="scss" scoped>
.provider {
  .provider-logo {
    width: 122px;
  }

  &__disabled {
    @apply cursor-default #{!important};
    .provider-logo {
      opacity: 30%;
    }
  }
}
</style>