previewer

This commit is contained in:
hamid zarghami
2026-03-14 12:00:25 +03:30
parent 27f57084e9
commit 703ed374f4
3 changed files with 498 additions and 419 deletions
@@ -0,0 +1,78 @@
import { type FC, useMemo } from 'react'
import BookPage from '@/pages/viewer/components/BookPage'
import { transformViewerDataToPages } from '@/pages/viewer/utils/dataTransformer'
import type { CatalogItemType } from '../types/Types'
import type { PageData } from '@/pages/viewer/types'
const PREVIEW_WIDTH = 64
const PREVIEW_HEIGHT = 89
const PAGE_BASE_WIDTH = 794
const PAGE_BASE_HEIGHT = 1123
const PREVIEW_SCALE = Math.min(
PREVIEW_WIDTH / PAGE_BASE_WIDTH,
PREVIEW_HEIGHT / PAGE_BASE_HEIGHT
)
function getFirstPageFromContent(content: string | undefined): PageData | null {
if (!content) return null
try {
const parsed = JSON.parse(content)
const pagesArray = Array.isArray(parsed) ? parsed : (parsed?.pages ?? [])
const transformed = transformViewerDataToPages({ pages: pagesArray })
return transformed[0] ?? null
} catch {
return null
}
}
type Props = {
item: CatalogItemType
}
const CatalogPreview: FC<Props> = ({ item }) => {
const firstPage = useMemo(
() => getFirstPageFromContent(item.content),
[item.content]
)
if (!firstPage) {
return (
<div
className='bg-gray-200 rounded-lg flex items-center justify-center shrink-0'
style={{ width: PREVIEW_WIDTH, height: PREVIEW_HEIGHT }}
>
<span className='text-[10px] text-gray-400'>بدون پیشنمایش</span>
</div>
)
}
return (
<div
className='rounded-lg overflow-hidden shrink-0 bg-white border border-gray-200 relative'
style={{ width: PREVIEW_WIDTH, height: PREVIEW_HEIGHT }}
dir='rtl'
>
<div
className='absolute'
style={{
top: 0,
right: 0,
transform: `scale(${PREVIEW_SCALE})`,
transformOrigin: 'top right',
width: PAGE_BASE_WIDTH,
height: PAGE_BASE_HEIGHT,
}}
>
<BookPage
page={firstPage}
scale={1}
pageWidth={PAGE_BASE_WIDTH}
pageHeight={PAGE_BASE_HEIGHT}
/>
</div>
</div>
)
}
export default CatalogPreview
@@ -4,6 +4,7 @@ import type { CatalogItemType } from '../types/Types'
import moment from 'moment-jalaali'
import { Link } from 'react-router-dom'
import { Paths } from '@/config/Paths'
import CatalogPreview from './CatalogPreview'
type Props = {
item: CatalogItemType
@@ -13,7 +14,7 @@ const CatalogueItem: FC<Props> = ({ item }) => {
return (
<div className='bg-white p-6 rounded-3xl w-full'>
<div className='flex gap-4 items-center'>
<div className='w-[64px] h-[89px] bg-gray-200'></div>
<CatalogPreview item={item} />
<div>
<h6>
{item.name}
@@ -23,7 +24,7 @@ const CatalogueItem: FC<Props> = ({ item }) => {
</div>
</div>
</div>
<div className='flex justify-end gap-1 items-center'>
<div className='flex justify-end gap-1 items-center mt-1'>
<Link to={Paths.viewer + `/${item.id}`}>
<div className='size-6 bg-[#EAECF4] rounded-md flex justify-center items-center'>
<Eye size={18} color='#0047FF' />