import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useEffect, useState } from 'react' import { Helmet } from 'react-helmet-async' import { useParams } from 'react-router-dom' import TagLink from '@/components/TagLink' import WikiBody from '@/components/WikiBody' import FieldError from '@/components/common/FieldError' import FormField from '@/components/common/FormField' import PageTitle from '@/components/common/PageTitle' import TabGroup, { Tab } from '@/components/common/TabGroup' import TagInput from '@/components/common/TagInput' import MainArea from '@/components/layout/MainArea' import { Button } from '@/components/ui/button' import { toast } from '@/components/ui/use-toast' import { SITE_TITLE } from '@/config' import { fetchMaterial, updateMaterial, } from '@/lib/materials' import { materialsKeys } from '@/lib/queryKeys' import { inputClass } from '@/lib/utils' import { useValidationErrors } from '@/lib/useValidationErrors' import type { FC } from 'react' type MaterialFormField = 'tag' | 'file' | 'url' | 'exportPaths' const MaterialDetailPage: FC = () => { const { id } = useParams () const qc = useQueryClient () const [exportPath, setExportPath] = useState ('') const [file, setFile] = useState (null) const [filePreview, setFilePreview] = useState ('') const [tag, setTag] = useState ('') const [url, setURL] = useState ('') const { baseErrors, fieldErrors, clearValidationErrors, applyValidationError } = useValidationErrors () const { data: material, isError, isLoading } = useQuery ({ queryKey: materialsKeys.show (id ?? ''), queryFn: () => fetchMaterial (id ?? ''), enabled: id != null}) const materialTitle = material ? material.tag?.name ?? `素材 #${ material.id }` : '' useEffect (() => { if (!(material)) return setTag (material.tag?.name ?? '') setURL (material.url ?? '') setExportPath (material.exportPaths.legacyDrive ?? '') if (material.file && material.contentType) { setFilePreview (material.file) setFile (null) } }, [material]) const invalidateMaterialQueries = async () => { await qc.invalidateQueries ({ queryKey: materialsKeys.root }) } const updateMutation = useMutation ({ mutationFn: async () => { const formData = new FormData if (tag.trim ()) formData.append ('tag', tag) if (file) formData.append ('file', file) if (url.trim ()) formData.append ('url', url) formData.append ('export_paths[legacy_drive]', exportPath) return await updateMaterial (id ?? '', formData) }, onSuccess: async data => { qc.setQueryData (materialsKeys.show (id ?? ''), data) await invalidateMaterialQueries () toast ({ title: '更新成功!' }) }, onError: error => { applyValidationError (error) toast ({ title: '更新失敗……', description: '入力を見直してください.' }) }}) const handleSubmit = () => { clearValidationErrors () updateMutation.mutate () } return ( {material && ( {`${ materialTitle } 素材照会 | ${ SITE_TITLE }`} )} {isLoading ? 'Loading...' : isError ? (

素材の取得に失敗しました.

) : material == null ? (

素材が見つかりませんでした.

) : ( <> {material.tag ? ( ) : materialTitle} {(material.file && material.contentType) && ( (/image\/.*/.test (material.contentType) && ( {material.tag?.name)) || (/video\/.*/.test (material.contentType) && (
) } export default MaterialDetailPage