ComImageShow.jsx 9.56 KB
import { useState, useEffect } from 'react'
import { Link, router } from '@inertiajs/react'
import * as Dialog from '@radix-ui/react-dialog'
import * as Form from '@radix-ui/react-form'
import ComImageStatusTag from './ComImageStatusTag'
import TagSearchInput from '../TagSearchInput'

export default function ComImageShow({ path, image, can_edit, can_approve, isAdmin = false }) {
  const [isModalOpen, setIsModalOpen] = useState(false)
  const [isApproveDialogOpen, setIsApproveDialogOpen] = useState(false)
  const [selectedTagIds, setSelectedTagIds] = useState(image.tags?.map(tag => tag.id) || [])
  const [isSubmitting, setIsSubmitting] = useState(false)
  
  // Update selectedTagIds when image changes
  useEffect(() => {
    if (image && image.tags) {
      setSelectedTagIds(image.tags.map(tag => tag.id));
    }
  }, [image])
  
  const handleApprove = () => {
    setIsSubmitting(true)
    router.patch(`${path}/approve`, {
      tag_ids: selectedTagIds
    }, {
      onSuccess: () => {
        setIsApproveDialogOpen(false)
        setIsSubmitting(false)
      },
      onError: () => {
        setIsSubmitting(false)
      }
    })
  }

  return (
    <div className="w-full bg-white shadow overflow-hidden sm:rounded-lg">
      <div className="w-full px-4 py-5 sm:px-6 flex justify-between items-center">
        <div className="flex-grow w-0">
          <h1 className="w-full text-2xl truncate font-bold text-gray-900">{image.title}</h1>
          <p className="mt-1 max-w-2xl text-sm text-gray-500">
{image.user.name}{' '}
            {new Date(image.created_at).toLocaleDateString()}{' '}上传
          </p>
        </div>
        <div className="flex-shrink-0 grid grid-cols-2 gap-2">
          {(can_edit || isAdmin) && (
            <Link
              href={`${path}/edit`}
              className="inline-flex items-center px-3 py-1.5 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
            >
              编辑
            </Link>
          )}
          {can_approve && image.status === 'pending' && (
            <>
              <button
                type="button"
                onClick={() => setIsApproveDialogOpen(true)}
                className="inline-flex items-center px-3 py-1.5 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"
              >
                通过
              </button>
              <Link
                href={`${path}/reject`}
                method="patch"
                as="button"
                className="inline-flex items-center px-3 py-1.5 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
              >
                拒绝
              </Link>
            </>
          )}
          {can_approve && (
            <Link
              href={`${path}`}
              method="delete"
              as="button"
              className="inline-flex items-center px-3 py-1.5 border border-gray-300 text-sm font-medium rounded-md shadow-sm text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
              onClick={(e) => {
                if (!confirm('确定要删除这张图片吗?')) {
                  e.preventDefault()
                }
              }}
            >
              删除
            </Link>
          )}
        </div>
      </div>

      <div className="border-t border-gray-200">
        <div className="flex flex-col md:flex-row">
          <div className="md:w-2/3 p-4">
            <div className="relative pb-[75%]">
              <img
                src={image.file_url}
                alt={image.title}
                className="absolute h-full w-full object-contain cursor-pointer"
                onClick={() => setIsModalOpen(true)}
              />
            </div>
          </div>
          <div className="md:w-1/3 p-4 border-t md:border-t-0 md:border-l border-gray-200">
            <div className="mb-4">
              <h3 className="text-lg font-medium text-gray-900">审核状态</h3>
              <ComImageStatusTag image={image} />
            </div>

            <div className="mb-4">
              <h3 className="text-lg font-medium text-gray-900">标签</h3>
              <div className="mt-2 flex flex-wrap gap-1">
                {image.tags.length > 0 ? (
                  image.tags.map((tag) => (
                    <span
                      key={tag.id}
                      className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800"
                    >
                      {tag.name}
                    </span>
                  ))
                ) : (
                  <p className="text-sm text-gray-500">无标签</p>
                )}
              </div>
            </div>

            <div className="mb-4">
              <h3 className="text-lg font-medium text-gray-900">上传者</h3>
              <p className="text-sm text-gray-500">{image.user.name}</p>
              <p className="text-sm text-gray-500">
                {image.user.email_address}
              </p>
            </div>

            <div className="mb-4">
              <h3 className="text-lg font-medium text-gray-900">
                上传日期
              </h3>
              <p className="text-sm text-gray-500">
                {new Date(image.created_at).toLocaleDateString()}
              </p>
            </div>
          </div>
        </div>
      </div>

      {/* 全屏图片模态框 */}
      <Dialog.Root open={isModalOpen} onOpenChange={setIsModalOpen}>
        <Dialog.Portal>
          <Dialog.Overlay className="fixed inset-0 bg-black/50 z-[100]" />
          <Dialog.Content className="fixed inset-0 flex items-center justify-center z-[150]">
            <Dialog.Title className="hidden"/>
            <div className="relative w-full h-full max-w-screen-xl max-h-screen p-4">
              <img
                src={image.file_url}
                alt={image.title}
                className="w-full h-full object-contain"
              />
              <Dialog.Close asChild>
                <button
                  className="absolute top-4 right-4 p-2 rounded-full bg-white/80 hover:bg-white text-gray-800"
                  aria-label="关闭"
                >
                  <svg
                    xmlns="http://www.w3.org/2000/svg"
                    className="h-6 w-6"
                    fill="none"
                    viewBox="0 0 24 24"
                    stroke="currentColor"
                  >
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      strokeWidth={2}
                      d="M6 18L18 6M6 6l12 12"
                    />
                  </svg>
                </button>
              </Dialog.Close>
            </div>
          </Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>

      {/* 审核通过确认对话框 */}
      <Dialog.Root open={isApproveDialogOpen} onOpenChange={setIsApproveDialogOpen}>
        <Dialog.Portal>
          {/* <Dialog.Overlay className="fixed inset-0 bg-black/50 z-[100]"  /> */}
          <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-md bg-white rounded-lg shadow-xl p-6 z-[200]">
            <Dialog.Title className="text-lg font-medium text-gray-900 mb-4">
              确认通过审核
            </Dialog.Title>
            <div className="mb-4">
              <p className="text-sm text-gray-500 mb-4">
                请为此图片选择合适的标签,然后点击确认通过审核。
              </p>
              
              <Form.Root>
                <Form.Field name="tags" className="space-y-2">
                  <Form.Label className="block text-sm font-medium text-gray-700">
                    标签
                  </Form.Label>
                  <Form.Control asChild>
                    <TagSearchInput
                      value={selectedTagIds}
                      onChange={(value) => setSelectedTagIds(value)}
                      placeholder="点击搜索图标添加标签"
                    />
                  </Form.Control>
                </Form.Field>
              </Form.Root>
            </div>
            
            <div className="flex justify-end space-x-3 mt-6">
              <Dialog.Close asChild>
                <button
                  type="button"
                  className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
                >
                  取消
                </button>
              </Dialog.Close>
              <button
                type="button"
                disabled={isSubmitting}
                onClick={handleApprove}
                className="inline-flex justify-center px-4 py-2 text-sm font-medium text-white bg-green-600 border border-transparent rounded-md shadow-sm hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 disabled:opacity-50"
              >
                {isSubmitting ? '处理中...' : '确认通过'}
              </button>
            </div>
          </Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>
    </div>
  )
}