/* eslint-disable eslint-comments/disable-enable-pair */ /* eslint-disable no-nested-ternary */ /* eslint-disable jsx-a11y/media-has-caption */ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ /* eslint-disable @typescript-eslint/no-unsafe-argument */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import clsx from 'clsx' import { Conditional } from 'components/Conditional' import { FormControl } from 'components/FormControl' import { FormGroup } from 'components/FormGroup' import { useInputState } from 'components/forms/FormInput.hooks' import { InputDateTime } from 'components/InputDateTime' import { Tooltip } from 'components/Tooltip' import { useGlobalSettings } from 'contexts/globalSettings' import { addLogItem } from 'contexts/log' import type { ChangeEvent } from 'react' import { useEffect, useMemo, useRef, useState } from 'react' import { toast } from 'react-hot-toast' import { OPEN_EDITION_UPDATABLE_FACTORY_ADDRESS, SG721_OPEN_EDITION_UPDATABLE_CODE_ID } from 'utils/constants' import { getAssetType } from 'utils/getAssetType' import { uid } from 'utils/random' import { TextInput } from '../forms/FormInput' import type { UploadMethod } from './OffChainMetadataUploadDetails' import type { MetadataStorageMethod } from './OpenEditionMinterCreator' interface CollectionDetailsProps { onChange: (data: CollectionDetailsDataProps) => void uploadMethod: UploadMethod coverImageUrl: string metadataStorageMethod: MetadataStorageMethod importedCollectionDetails?: CollectionDetailsDataProps } export interface CollectionDetailsDataProps { name: string description: string symbol: string imageFile: File[] externalLink?: string startTradingTime?: string explicit: boolean updatable: boolean } export const CollectionDetails = ({ onChange, uploadMethod, metadataStorageMethod, coverImageUrl, importedCollectionDetails, }: CollectionDetailsProps) => { const [coverImage, setCoverImage] = useState(null) const [timestamp, setTimestamp] = useState() const [explicit, setExplicit] = useState(false) const [updatable, setUpdatable] = useState(false) const { timezone } = useGlobalSettings() const initialRender = useRef(true) const coverImageInputRef = useRef(null) const nameState = useInputState({ id: 'name', name: 'name', title: 'Name', placeholder: 'My Awesome Collection', }) const descriptionState = useInputState({ id: 'description', name: 'description', title: 'Description', placeholder: 'My Awesome Collection Description', }) const symbolState = useInputState({ id: 'symbol', name: 'symbol', title: 'Symbol', placeholder: 'SYMBOL', }) const externalLinkState = useInputState({ id: 'external-link', name: 'externalLink', title: 'External Link (optional)', placeholder: 'https://my-collection...', }) useEffect(() => { try { const data: CollectionDetailsDataProps = { name: nameState.value, description: descriptionState.value, symbol: symbolState.value, imageFile: coverImage ? [coverImage] : [], externalLink: externalLinkState.value || undefined, startTradingTime: timestamp ? (timestamp.getTime() * 1_000_000).toString() : '', explicit, updatable, } onChange(data) // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { toast.error(error.message, { style: { maxWidth: 'none' } }) addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() }) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [ nameState.value, descriptionState.value, symbolState.value, externalLinkState.value, coverImage, timestamp, explicit, updatable, ]) const selectCoverImage = (event: ChangeEvent) => { if (event.target.files === null) return toast.error('Error selecting cover image') if (event.target.files.length === 0) { setCoverImage(null) return toast.error('No files selected.') } const reader = new FileReader() reader.onload = (e) => { if (!e.target?.result) return toast.error('Error parsing file.') if (!event.target.files) return toast.error('No files selected.') const imageFile = new File([e.target.result], event.target.files[0].name, { type: 'image/jpg' }) setCoverImage(imageFile) } reader.readAsArrayBuffer(event.target.files[0]) } useEffect(() => { setCoverImage(null) // empty the element so that the same file can be selected again if (coverImageInputRef.current) coverImageInputRef.current.value = '' }, [metadataStorageMethod]) useEffect(() => { if (initialRender.current) { initialRender.current = false } else if (updatable) { toast.success('Token metadata will be updatable upon collection creation.', { style: { maxWidth: 'none' }, icon: '✅📝', }) } else { toast.error('Token metadata will not be updatable upon collection creation.', { style: { maxWidth: 'none' }, icon: '⛔🔏', }) } }, [updatable]) useEffect(() => { if (importedCollectionDetails) { nameState.onChange(importedCollectionDetails.name) descriptionState.onChange(importedCollectionDetails.description) symbolState.onChange(importedCollectionDetails.symbol) //setCoverImage(importedCollectionDetails.imageFile[0] || null) externalLinkState.onChange(importedCollectionDetails.externalLink || '') setTimestamp( importedCollectionDetails.startTradingTime ? new Date(parseInt(importedCollectionDetails.startTradingTime) / 1_000_000) : undefined, ) setExplicit(importedCollectionDetails.explicit) setUpdatable(importedCollectionDetails.updatable) } }, [importedCollectionDetails]) const videoPreview = useMemo(() => { if (uploadMethod === 'new' && coverImage) { return (