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 moment from 'moment-jalaali'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import { Paths } from '@/config/Paths'
|
import { Paths } from '@/config/Paths'
|
||||||
|
import CatalogPreview from './CatalogPreview'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
item: CatalogItemType
|
item: CatalogItemType
|
||||||
@@ -13,7 +14,7 @@ const CatalogueItem: FC<Props> = ({ item }) => {
|
|||||||
return (
|
return (
|
||||||
<div className='bg-white p-6 rounded-3xl w-full'>
|
<div className='bg-white p-6 rounded-3xl w-full'>
|
||||||
<div className='flex gap-4 items-center'>
|
<div className='flex gap-4 items-center'>
|
||||||
<div className='w-[64px] h-[89px] bg-gray-200'></div>
|
<CatalogPreview item={item} />
|
||||||
<div>
|
<div>
|
||||||
<h6>
|
<h6>
|
||||||
{item.name}
|
{item.name}
|
||||||
@@ -23,7 +24,7 @@ const CatalogueItem: FC<Props> = ({ item }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</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}`}>
|
<Link to={Paths.viewer + `/${item.id}`}>
|
||||||
<div className='size-6 bg-[#EAECF4] rounded-md flex justify-center items-center'>
|
<div className='size-6 bg-[#EAECF4] rounded-md flex justify-center items-center'>
|
||||||
<Eye size={18} color='#0047FF' />
|
<Eye size={18} color='#0047FF' />
|
||||||
|
|||||||
@@ -487,7 +487,7 @@ const BookPage = forwardRef<HTMLDivElement, BookPageProps>(
|
|||||||
{page.elements.map((element, index) => renderObject(element, index))}
|
{page.elements.map((element, index) => renderObject(element, index))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
BookPage.displayName = 'BookPage';
|
BookPage.displayName = 'BookPage';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user