import PostOriginalCreatedTimeField from '@/components/PostOriginalCreatedTimeField' import FieldError from '@/components/common/FieldError' import FieldWarning from '@/components/common/FieldWarning' import FormField from '@/components/common/FormField' import PostImportStatusBadge from '@/components/posts/import/PostImportStatusBadge' import ThumbnailPreview from '@/components/posts/import/ThumbnailPreview' import { effectivePostImportStatus } from '@/components/posts/import/postImportRowStatus' import { Button } from '@/components/ui/button' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog' import { inputClass } from '@/lib/utils' import type { FC } from 'react' import { useEffect, useState } from 'react' import type { PostImportOrigin, PostImportRow } from '@/lib/postImportSession' type Draft = { url: string title: string thumbnailBase: string originalCreatedFrom: string originalCreatedBefore: string duration: string tags: string parentPostIds: string } type Props = { open: boolean row: PostImportRow | null saving: boolean onOpenChange: (open: boolean) => void onSave: (draft: Draft) => Promise } const originOf = ( row: PostImportRow, field: string, ): PostImportOrigin => row.provenance[field] ?? 'automatic' const originalCreatedOrigin = (row: PostImportRow): PostImportOrigin => originOf (row, 'originalCreatedFrom') === 'manual' || originOf (row, 'originalCreatedBefore') === 'manual' ? 'manual' : 'automatic' const buildDraft = (row: PostImportRow): Draft => ({ url: row.url, title: String (row.attributes.title ?? ''), thumbnailBase: String (row.attributes.thumbnailBase ?? ''), originalCreatedFrom: String (row.attributes.originalCreatedFrom ?? ''), originalCreatedBefore: String (row.attributes.originalCreatedBefore ?? ''), duration: String (row.attributes.duration ?? ''), tags: String (row.attributes.tags ?? ''), parentPostIds: String (row.attributes.parentPostIds ?? '') }) const groupedMessages = ( ...values: Array ): string[] => values.flatMap (value => value ?? []) const PostImportRowDialog: FC = ( { open, row, saving, onOpenChange, onSave }, ) => { const [draft, setDraft] = useState (null) useEffect (() => { if (open && row) setDraft (buildDraft (row)) }, [open, row]) if (!(row) || !(draft)) return null const update = ( key: Key, value: Draft[Key], ) => { setDraft (current => current ? { ...current, [key]: value } : current) } const save = async () => { if (await onSave (draft)) onOpenChange (false) } return ( 投稿を編輯 投稿 {row.sourceRow} の内容を確認し、必要な項目を編輯してください.
update ('url', value)}/> update ('title', value)}/> update ('thumbnailBase', value)}/> } originalCreatedFrom={draft.originalCreatedFrom || null} setOriginalCreatedFrom={value => update ('originalCreatedFrom', value ?? '')} originalCreatedBefore={draft.originalCreatedBefore || null} setOriginalCreatedBefore={value => update ('originalCreatedBefore', value ?? '')} errors={groupedMessages ( row.validationErrors.originalCreatedAt, row.validationErrors.originalCreatedFrom, row.validationErrors.originalCreatedBefore, row.importErrors?.originalCreatedAt, row.importErrors?.originalCreatedFrom, row.importErrors?.originalCreatedBefore, )}/> update ('duration', value)}/> update ('tags', value)}/> update ('parentPostIds', value)}/>
) } const DialogTextField = ( { label, value, origin, warnings, errors, onChange }: { label: string value: string origin: PostImportOrigin warnings?: string[] errors?: string[] onChange: (value: string) => void }, ) => ( } messages={errors}> {({ describedBy, invalid }) => ( <> onChange (ev.target.value)} aria-describedby={describedBy} aria-invalid={invalid} className={inputClass (invalid)}/> )} ) const DialogAreaField = ( { label, value, origin, warnings, errors, onChange }: { label: string value: string origin: PostImportOrigin warnings?: string[] errors?: string[] onChange: (value: string) => void }, ) => ( } messages={errors}> {({ describedBy, invalid }) => ( <>