Files
dmail-admin/src/pages/setting/personality/components/ImageRenderer.tsx
T
hamid zarghami 098d39284b remove logs
2025-07-15 16:14:34 +03:30

180 lines
6.6 KiB
TypeScript

import { FC } from 'react'
import { ImageType, ImageSize, HorizontalAlignment, VerticalAlignment, ElementType, PersonalityDataType } from '../types/Types'
import { usePersonalityStore } from '../store/Store'
interface ImageRendererProps {
images: ImageType[]
itemId: string
sectionKey: keyof PersonalityDataType
}
const ImageRenderer: FC<ImageRendererProps> = ({ images, itemId, sectionKey }) => {
const { selectedElement, setSelectedElement } = usePersonalityStore()
if (!images || images.length === 0) return null
const handleImageClick = (e: React.MouseEvent, imageId: string) => {
// جلوگیری از propagation به parent handlers
e.stopPropagation()
e.preventDefault()
setSelectedElement({
type: ElementType.IMAGE,
elementId: imageId,
itemId,
sectionKey,
})
}
// تابع‌های helper برای تبدیل enum به string
const getHorizontalAlign = (alignment?: HorizontalAlignment) => {
switch (alignment) {
case HorizontalAlignment.LEFT:
return 'left'
case HorizontalAlignment.RIGHT:
return 'right'
case HorizontalAlignment.CENTER:
default:
return 'center'
}
}
const getVerticalAlign = (verticalAlignment?: VerticalAlignment) => {
switch (verticalAlignment) {
case VerticalAlignment.TOP:
return 'top'
case VerticalAlignment.BOTTOM:
return 'bottom'
case VerticalAlignment.MIDDLE:
default:
return 'middle'
}
}
const getImageStyle = (image: ImageType) => {
return {
width: image.width || '100%',
height: image.height || 'auto',
border: '0',
pointerEvents: 'none' as const // Prevent double click handling
}
}
const shouldUseBackgroundImage = (imageSize: ImageSize) => {
return imageSize === ImageSize.REPEAT ||
imageSize === ImageSize.REPEAT_X ||
imageSize === ImageSize.REPEAT_Y
}
const getBackgroundStyle = (image: ImageType) => {
let backgroundRepeat = 'no-repeat'
switch (image.size) {
case ImageSize.REPEAT:
backgroundRepeat = 'repeat'
break
case ImageSize.REPEAT_X:
backgroundRepeat = 'repeat-x'
break
case ImageSize.REPEAT_Y:
backgroundRepeat = 'repeat-y'
break
default:
backgroundRepeat = 'no-repeat'
break
}
const horizontal = image.alignment === HorizontalAlignment.LEFT ? 'left' :
image.alignment === HorizontalAlignment.RIGHT ? 'right' : 'center'
const vertical = image.verticalAlignment === VerticalAlignment.TOP ? 'top' :
image.verticalAlignment === VerticalAlignment.BOTTOM ? 'bottom' : 'center'
return {
backgroundImage: `url(${image.src})`,
backgroundPosition: `${horizontal} ${vertical}`,
backgroundRepeat,
width: image.width || '100%',
height: image.height || '100px'
}
}
const renderImage = (image: ImageType) => {
const imageWrapper = (
<div
data-element-type="image"
onClick={(e) => handleImageClick(e, image.id)}
style={{
cursor: 'pointer',
outline: selectedElement?.elementId === image.id ? '2px dashed #0038FF' : 'none',
outlineOffset: '2px',
borderRadius: '4px',
padding: '2px',
display: 'inline-block',
minWidth: '20px',
minHeight: '20px'
}}
>
{shouldUseBackgroundImage(image.size) ? (
// برای pattern های repeat از background استفاده می‌کنیم
<div style={getBackgroundStyle(image)}>
&nbsp;
</div>
) : (
// برای تصاویر عادی
image.size === ImageSize.CONTAIN ? (
// برای contain از table wrapper استفاده می‌کنیم تا نسبت حفظ شود
<table width={image.width || '100%'} cellPadding="0" cellSpacing="0" border={0}>
<tbody>
<tr>
<td align="center" valign="middle" style={{ textAlign: 'center' }}>
<img
src={image.src}
alt={image.alt || 'تصویر آپلود شده'}
width={image.width || '100%'}
height={image.height || 'auto'}
style={getImageStyle(image)}
/>
</td>
</tr>
</tbody>
</table>
) : (
// برای cover و auto
<img
src={image.src}
alt={image.alt || 'تصویر آپلود شده'}
width={image.width || '100%'}
height={image.height || 'auto'}
style={getImageStyle(image)}
/>
)
)}
</div>
)
return imageWrapper
}
return (
<>
{images.map((image, imageIndex) => (
<table key={image.id} width="100%" cellPadding="0" cellSpacing="0" border={0}>
<tbody>
<tr>
<td
align={getHorizontalAlign(image.alignment)}
valign={getVerticalAlign(image.verticalAlignment)}
style={{
paddingBottom: imageIndex < images.length - 1 ? '4px' : '0'
}}
>
{renderImage(image)}
</td>
</tr>
</tbody>
</table>
))}
</>
)
}
export default ImageRenderer