import { AssetLevelEnum, AssetStatus, AttachmentClassification, AttachmentData, ChainBaseEvent, ChainBaseEventData, CustomerAsset, DeviceData, LoggerType, SKIPPABLE_ASSET_STEPS, SellingMethodEnum, SerializableValue, SerializedImage, SerializedProp, SerializedStep, StepEnum, SubjectDataReferenceItem, VerifyTypeEnum, WeatherData, getAssetVerifyStatusBySteps, } from '@bit-ui-libs/common'; import { UseQueryOptions, useQuery } from '@tanstack/react-query'; import { useCallback } from 'react'; import { useChainService, useUserId } from '../../../stores'; import { formatDescription } from '../utils'; import { useChainTypeFromEvent } from './use-chain-type-from-event'; type UseGetTokenDetailsOpts = UseQueryOptions & { eventId: string; queryKey: SerializableValue[]; separator?: string; logger?: LoggerType; }; export function useGetTokenDetails(opts: UseGetTokenDetailsOpts): UseGetTokenDetails { const { eventId, queryKey, logger } = opts; const userId = useUserId(); const chainType = useChainTypeFromEvent(eventId); const service = useChainService(chainType); const getMainPhotoUrl = useCallback( async (event: ChainBaseEvent, asset: CustomerAsset, thumbnail?: boolean) => { if (event && event.attachments && event.attachments.length > 0) { const mainAttachment = event.attachments.filter((a) => a.isMain).shift() ?? event.attachments.shift(); if (mainAttachment) return thumbnail ? mainAttachment.thumbUrl : mainAttachment.url; } if (asset && asset.serializedImages && asset.serializedImages.length > 0) { const mainPhoto = asset.serializedImages.filter((i) => i.isMain).shift() ?? asset.serializedImages.shift(); if (mainPhoto) return service.getAttachmentImageUrl(mainPhoto.docId, thumbnail); } return ''; }, [service] ); const { data, isLoading, refetch } = useQuery({ queryKey: [...queryKey, chainType, userId, eventId], queryFn: async () => { logger?.debug('Getting Token Details:', queryKey, eventId); const event = await service.getEvent(eventId); const asset = await service.getDetailsByEvent(eventId); // Compute Attachment ID to pass it to "getAttachmentLink" query (below) const mainAttachmentUrl = await getMainPhotoUrl(event, asset, true); const qrCodeAttachment = event && event.attachments && event.attachments.length > 0 ? event.attachments.filter((a) => a.classification === AttachmentClassification.QrCode).shift() : null; // Not sure if this is right, might need to be updated const description = formatDescription(asset.typeName || ''); const verifyType = getAssetVerifyStatusBySteps(asset); const categories = asset?.serializedCategories?.join(opts?.separator ?? ' | '); const isOwner = asset.ownerId === userId; const isRegistrationComplete = asset.serializedSteps .filter((s) => s.step && !SKIPPABLE_ASSET_STEPS.includes(s.step) && s.enabled) .filter((s) => s.isRequired === true) .every((s) => s.finished) && asset.isMinted; const isQrAttached = ( asset.serializedSteps ?.sort((a, b) => a?.order - b?.order) ?.filter((s) => s.finished && s.step === StepEnum.QRCODE) ?? [] ).length > 0; // IMPORTANT! asset.serializedSteps are not guaranteed to be ordered by "order" const lastFinishedStep = asset.serializedSteps ?.sort((a, b) => a?.order - b?.order) ?.filter((s) => s.finished) .pop()?.step; const tokenDetails: GetTokenDetailsData = { ...event, ...asset, mainAttachmentUrl, qrCodeAttachment, description, verifyType, categories, isOwner, isRegistrationComplete, isQrAttached, lastFinishedStep, }; return tokenDetails; }, enabled: Boolean(eventId), }); return { data, isLoading, refetch }; } type GetTokenDetailsData = ComputedTokenDetails & { id: string; application: string; assetType?: string; device: DeviceData; weather: WeatherData; status: AssetStatus; subjectType: string; attachments?: AttachmentData[] | null; eventDate?: string | null; data?: ChainBaseEventData; subjectReferences: SubjectDataReferenceItem[]; appName: string; typeId: string; typeName: string; level: AssetLevelEnum; name: string; ownerId: string; orgId: string; serializedSteps: SerializedStep[]; serializedProps: SerializedProp[]; serializedImages: SerializedImage[]; serializedCategories: string[]; qrCodeRef?: string | null; rfIdRef?: string | null; eventIdRef: string; city?: string | null; state?: string | null; country?: string | null; isMinted: boolean; isVerifiedByWitness: boolean; createdAt: string; updatedAt: string; mintedAt: string; sellingMethod: SellingMethodEnum | null; }; // Custom properties interface ComputedTokenDetails { mainAttachmentUrl?: string; qrCodeAttachment?: AttachmentData | null; description: string; verifyType: VerifyTypeEnum; categories?: string; isOwner: boolean; isRegistrationComplete: boolean; isQrAttached: boolean; lastFinishedStep?: StepEnum; } interface UseGetTokenDetails { data?: GetTokenDetailsData; isLoading: boolean; refetch: () => void; }