200 lines
8.6 KiB
TypeScript
200 lines
8.6 KiB
TypeScript
import Button from '@/components/Button'
|
|
import Select from '@/components/Select'
|
|
import UploadBoxDraggble from '@/components/UploadBoxDraggble'
|
|
import { Add, AlignBottom, AlignHorizontally, AlignLeft, AlignRight, AlignTop, AlignVertically } from 'iconsax-react'
|
|
import { FC, useState } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { usePersonalityStore } from '../store/Store'
|
|
import { ImageSize, HorizontalAlignment, VerticalAlignment } from '../types/Types'
|
|
|
|
const ImageSideBar: FC = () => {
|
|
|
|
const { t } = useTranslation()
|
|
const { addImageToActiveItem, activeSection, activeItemIndex, data } = usePersonalityStore()
|
|
|
|
const [imageSrc, setImageSrc] = useState<string>('')
|
|
const [imageSize, setImageSize] = useState<ImageSize>(ImageSize.COVER)
|
|
const [horizontalAlignment, setHorizontalAlignment] = useState<HorizontalAlignment>(HorizontalAlignment.CENTER)
|
|
const [verticalAlignment, setVerticalAlignment] = useState<VerticalAlignment>(VerticalAlignment.MIDDLE)
|
|
const [isLoading, setIsLoading] = useState<boolean>(false)
|
|
const [isReset, setIsReset] = useState<boolean>(false)
|
|
|
|
const sizeOptions = [
|
|
{ label: 'کاور - تمام فضا را پوشش دهد (Cover)', value: ImageSize.COVER },
|
|
{ label: 'در مقیاس - در فضا جا شود (Contain)', value: ImageSize.CONTAIN },
|
|
{ label: 'تکرار - عکس تکرار شود (Repeat)', value: ImageSize.REPEAT },
|
|
{ label: 'تکرار افقی (Repeat-X)', value: ImageSize.REPEAT_X },
|
|
{ label: 'تکرار عمودی (Repeat-Y)', value: ImageSize.REPEAT_Y },
|
|
{ label: 'بدون تکرار (No-Repeat)', value: ImageSize.NO_REPEAT },
|
|
{ label: 'اندازه اصلی (Auto)', value: ImageSize.AUTO }
|
|
]
|
|
|
|
const handleImageUpload = (files: File[]) => {
|
|
if (files.length === 0) return
|
|
|
|
const file = files[0] // فقط اولین فایل را در نظر میگیریم
|
|
// در اینجا باید فایل آپلود شود و URL برگردانده شود
|
|
// فعلاً از FileReader استفاده میکنم برای تست
|
|
const reader = new FileReader()
|
|
reader.onload = (e) => {
|
|
const result = e.target?.result as string
|
|
setImageSrc(result)
|
|
}
|
|
reader.readAsDataURL(file)
|
|
}
|
|
|
|
const handleAddImage = () => {
|
|
if (!imageSrc) return
|
|
|
|
console.log('Store state before adding image:', {
|
|
activeSection,
|
|
activeItemIndex,
|
|
hasActiveItem: activeSection && data[activeSection as keyof typeof data]?.items[activeItemIndex],
|
|
})
|
|
|
|
// Validation
|
|
if (!activeSection) {
|
|
console.error('No active section selected')
|
|
return
|
|
}
|
|
|
|
const sectionData = data[activeSection as keyof typeof data]
|
|
if (!sectionData?.items || activeItemIndex >= sectionData.items.length) {
|
|
console.error('No active item found or invalid index', {
|
|
activeItemIndex,
|
|
itemsLength: sectionData?.items?.length
|
|
})
|
|
return
|
|
}
|
|
|
|
console.log('Adding image with data:', {
|
|
src: imageSrc,
|
|
alt: 'عکس آپلود شده',
|
|
size: imageSize,
|
|
alignment: horizontalAlignment,
|
|
verticalAlignment,
|
|
})
|
|
|
|
setIsLoading(true)
|
|
|
|
try {
|
|
addImageToActiveItem({
|
|
src: imageSrc,
|
|
alt: 'عکس آپلود شده',
|
|
size: imageSize,
|
|
alignment: horizontalAlignment,
|
|
verticalAlignment,
|
|
})
|
|
|
|
console.log('Image added successfully')
|
|
|
|
// Reset form after adding
|
|
setImageSrc('')
|
|
setImageSize(ImageSize.COVER)
|
|
setHorizontalAlignment(HorizontalAlignment.CENTER)
|
|
setVerticalAlignment(VerticalAlignment.MIDDLE)
|
|
setIsReset(true)
|
|
setTimeout(() => {
|
|
setIsReset(false)
|
|
}, 1000)
|
|
} catch (error) {
|
|
console.error('Error adding image:', error)
|
|
} finally {
|
|
setIsLoading(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<div className='text-lg'>{t('setting.image')}</div>
|
|
|
|
<div className='mt-8'>
|
|
<UploadBoxDraggble
|
|
label={t('setting.upload_image')}
|
|
onChange={handleImageUpload}
|
|
isReset={isReset}
|
|
/>
|
|
</div>
|
|
|
|
<div className='mt-5'>
|
|
<Select
|
|
items={sizeOptions}
|
|
label={t('setting.size')}
|
|
value={imageSize}
|
|
onChange={(e) => setImageSize(e.target.value as ImageSize)}
|
|
placeholder={t('setting.size')}
|
|
/>
|
|
</div>
|
|
|
|
<div className='mt-5 flex justify-between'>
|
|
<div>
|
|
<div className='text-sm'>
|
|
{t('setting.horizontal_position')}
|
|
</div>
|
|
<div className='mt-3 flex gap-4'>
|
|
<div
|
|
className={`cursor-pointer p-1 rounded ${horizontalAlignment === HorizontalAlignment.RIGHT ? 'bg-blue-100' : ''}`}
|
|
onClick={() => setHorizontalAlignment(HorizontalAlignment.RIGHT)}
|
|
>
|
|
<AlignRight size={20} color={horizontalAlignment === HorizontalAlignment.RIGHT ? '#0038FF' : '#000'} />
|
|
</div>
|
|
<div
|
|
className={`cursor-pointer p-1 rounded ${horizontalAlignment === HorizontalAlignment.CENTER ? 'bg-blue-100' : ''}`}
|
|
onClick={() => setHorizontalAlignment(HorizontalAlignment.CENTER)}
|
|
>
|
|
<AlignVertically size={20} color={horizontalAlignment === HorizontalAlignment.CENTER ? '#0038FF' : '#000'} />
|
|
</div>
|
|
<div
|
|
className={`cursor-pointer p-1 rounded ${horizontalAlignment === HorizontalAlignment.LEFT ? 'bg-blue-100' : ''}`}
|
|
onClick={() => setHorizontalAlignment(HorizontalAlignment.LEFT)}
|
|
>
|
|
<AlignLeft size={20} color={horizontalAlignment === HorizontalAlignment.LEFT ? '#0038FF' : '#000'} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<div className='text-sm'>
|
|
{t('setting.vertical_position')}
|
|
</div>
|
|
<div className='mt-3 flex gap-4'>
|
|
<div
|
|
className={`cursor-pointer p-1 rounded ${verticalAlignment === VerticalAlignment.BOTTOM ? 'bg-blue-100' : ''}`}
|
|
onClick={() => setVerticalAlignment(VerticalAlignment.BOTTOM)}
|
|
>
|
|
<AlignBottom size={20} color={verticalAlignment === VerticalAlignment.BOTTOM ? '#0038FF' : '#000'} />
|
|
</div>
|
|
<div
|
|
className={`cursor-pointer p-1 rounded ${verticalAlignment === VerticalAlignment.MIDDLE ? 'bg-blue-100' : ''}`}
|
|
onClick={() => setVerticalAlignment(VerticalAlignment.MIDDLE)}
|
|
>
|
|
<AlignHorizontally size={20} color={verticalAlignment === VerticalAlignment.MIDDLE ? '#0038FF' : '#000'} />
|
|
</div>
|
|
<div
|
|
className={`cursor-pointer p-1 rounded ${verticalAlignment === VerticalAlignment.TOP ? 'bg-blue-100' : ''}`}
|
|
onClick={() => setVerticalAlignment(VerticalAlignment.TOP)}
|
|
>
|
|
<AlignTop size={20} color={verticalAlignment === VerticalAlignment.TOP ? '#0038FF' : '#000'} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='mt-7'>
|
|
<Button
|
|
onClick={handleAddImage}
|
|
className='bg-[#ECEEF5] text-black'
|
|
disabled={!imageSrc}
|
|
loading={isLoading}
|
|
>
|
|
<div className='flex justify-center items-center gap-2'>
|
|
<Add size={24} color='black' />
|
|
<span>{t('setting.add_image')}</span>
|
|
</div>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default ImageSideBar |