| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- 'use client'
- import type { FC } from 'react'
- import { createPortal } from 'react-dom'
- import { RiCloseLine } from '@remixicon/react'
- import { useTranslation } from 'react-i18next'
- import Loading from '@/app/components/base/loading'
- import { useEffect, useState } from 'react'
- import { KKFILEVIEW_URL } from '@/config'
- type KKFileViewPreviewProps = {
- url: string
- fileName: string
- onCancel: () => void
- }
- const KKFileViewPreview: FC<KKFileViewPreviewProps> = ({
- url,
- fileName,
- onCancel,
- }) => {
- const { t } = useTranslation()
- const [isLoading, setIsLoading] = useState(true)
- const [previewUrl, setPreviewUrl] = useState('')
- useEffect(() => {
- if (!KKFILEVIEW_URL) {
- console.error('KKFILEVIEW_URL is not configured')
- return
- }
- if (url) {
- // kkFileView official doc: first Base64 encode, then URL encode
- // Reference: https://file.kkview.cn/integrated
- const base64Url = btoa(url)
- const kkFileViewUrl = `${KKFILEVIEW_URL}/onlinePreview?url=${encodeURIComponent(base64Url)}`
- setPreviewUrl(kkFileViewUrl)
- }
- }, [url])
- const handleIframeLoad = () => {
- setIsLoading(false)
- }
- const handleIframeError = () => {
- setIsLoading(false)
- console.error('Failed to load document preview')
- }
- return createPortal(
- <div
- className="fixed inset-0 z-[1000] flex items-center justify-center bg-black/80"
- onClick={onCancel}
- >
- <div
- className="relative h-[95vh] w-[95vw] max-w-[1400px] overflow-hidden rounded-lg bg-white shadow-2xl"
- onClick={e => e.stopPropagation()}
- >
- {/* Header */}
- <div className="flex h-14 items-center justify-between border-b border-divider-subtle bg-background-section-burn px-6">
- <div className="flex items-center gap-2">
- <span className="system-md-semibold text-text-primary">
- {t('datasetDocuments.list.preview.title')}
- </span>
- <span className="system-sm-regular text-text-tertiary">
- {fileName}
- </span>
- </div>
- <button
- onClick={onCancel}
- className="flex h-8 w-8 items-center justify-center rounded-lg hover:bg-state-base-hover"
- >
- <RiCloseLine className="h-5 w-5 text-text-tertiary" />
- </button>
- </div>
- {/* Preview Content */}
- <div className="relative h-[calc(100%-3.5rem)] w-full">
- {isLoading && (
- <div className="absolute inset-0 z-10 flex items-center justify-center bg-white">
- <Loading type="app" />
- </div>
- )}
- {previewUrl
- ? (
- <iframe
- src={previewUrl}
- className="h-full w-full border-0"
- title={fileName}
- onLoad={handleIframeLoad}
- onError={handleIframeError}
- sandbox="allow-same-origin allow-scripts allow-popups allow-forms"
- />
- )
- : (
- <div className="flex h-full items-center justify-center">
- <div className="text-center">
- <p className="text-text-tertiary">
- {t('datasetDocuments.list.preview.error')}
- </p>
- </div>
- </div>
- )}
- </div>
- </div>
- </div>,
- document.body,
- )
- }
- export default KKFileViewPreview
|