previewer
This commit is contained in:
@@ -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' />
|
||||
|
||||
Reference in New Issue
Block a user