kodadot/nft-gallery

View on GitHub
components/base/BaseTokenForm.vue

Summary

Maintainability
Test Coverage
<template>
  <div>
    <slot name="header" />

    <NeoField>
      <Auth />
    </NeoField>

    <CollectionSelect
      :collections="collections"
      :show-explainer-text="showExplainerText"
      @change-selected-collection="onCollectionSelected"
    />

    <transition-group name="fade">
      <template v-if="vSelectedCollection">
        <MetadataUpload
          ref="upload"
          key="file"
          v-model="vFile"
          :required="true"
          :label="$t('mint.nft.drop')"
          expanded
          preview
        />

        <BasicInput
          ref="nftName"
          key="name"
          v-model="vName"
          required
          :label="$t('mint.nft.name.label')"
          :message="$t('mint.nft.name.message')"
          :placeholder="$t('mint.nft.name.placeholder')"
          expanded
          spellcheck="true"
          maxlength="60"
        />

        <BasicInput
          key="description"
          v-model="vDescription"
          maxlength="500"
          class="my-5"
          type="textarea"
          spellcheck="true"
          :label="$t('mint.nft.description.label')"
          :message="$t('mint.nft.description.message')"
          :placeholder="$t('mint.nft.description.placeholder')"
        />

        <BasicNumberInput
          v-if="hasCopies"
          key="copies"
          v-model="vCopies"
          :label="$t('mint.nft.edition.label')"
          :message="$t('mint.nft.edition.message')"
          :placeholder="$t('mint.nft.edition.placeholder')"
          expanded
          :min="1"
          :max="clickableMax"
        />

        <MetadataUpload
          v-if="secondaryFileVisible"
          key="secondaryFile"
          v-model="vSecondFile"
          :label="$t('mint.nft.cover')"
          icon="file-image"
          preview
          accept="image/png, image/jpeg, image/gif"
          expanded
        />

        <slot name="main" />

        <slot name="footer" />
      </template>
    </transition-group>
  </div>
</template>

<script setup lang="ts">
import { NeoField } from '@kodadot1/brick'
import { useVModel } from '@vueuse/core'
import { MediaType } from '../rmrk/types'
import { resolveMedia } from '../rmrk/utils'
import type { BaseMintedCollection as MintedCollection } from './types'
import Auth from '@/components/shared/Auth.vue'
import MetadataUpload from '@/components/shared/DropUpload.vue'
import BasicInput from '@/components/shared/form/BasicInput.vue'
import BasicNumberInput from '@/components/shared/form/BasicNumberInput.vue'
import CollectionSelect from '@/components/base/CollectionSelect.vue'

const props = defineProps({
  label: {
    type: String,
    default: 'context',
  },
  collections: {
    type: Array,
    default: () => [],
  },
  hasCopies: {
    type: Boolean,
    default: true,
  },
  showExplainerText: {
    type: Boolean,
    default: false,
  },
  name: String,
  description: String,
  file: Blob,
  selectedCollection: Object,
  copies: Number,
  secondFile: Blob,
})

const emit = defineEmits([
  'update:name',
  'update:description',
  'update:file',
  'update:selectedCollection',
  'update:copies',
  'update:secondFile',
])

const nftName = ref<InstanceType<typeof BasicInput>>()
const upload = ref<InstanceType<typeof MetadataUpload>>()

const vName = useVModel(props, 'name', emit)

const vDescription = useVModel(props, 'description', emit)

const vFile = useVModel(props, 'file', emit)

// const vSelectedCollection = useVModel(props, 'selectedCollection', emit)
const vSelectedCollection = ref()

const vCopies = useVModel(props, 'copies', emit)

const vSecondFile = useVModel(props, 'secondFile', emit)

const checkValidity = () => {
  const nftNameValid = nftName.value?.checkValidity()
  const uploadValid = upload.value?.checkValidity()
  return nftNameValid && uploadValid
}

const onCollectionSelected = (collection: MintedCollection) => {
  vSelectedCollection.value = collection
}

const clickableMax = ref(Infinity)

const fileType = computed(() => resolveMedia(vFile.value?.type))

const secondaryFileVisible = computed(() => {
  const ft = fileType.value
  return ![MediaType.UNKNOWN, MediaType.IMAGE].some(t => t === ft)
})

defineExpose({ checkValidity })
</script>