219 lines
9.5 KiB
TypeScript
219 lines
9.5 KiB
TypeScript
import { FC, useState, useEffect } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import UploadBoxDraggble from '@/components/UploadBoxDraggble';
|
|
import ColorPicker from '@/components/ColorPicker';
|
|
import { usePersonalityStore } from '../store/Store';
|
|
import { SectionItemType, BackgroundSize, SectionName } from '../types/Types';
|
|
import Select from '@/components/Select';
|
|
import { useSingleUpload } from '../hooks/usePersonalityData';
|
|
import { toast } from '@/components/Toast';
|
|
|
|
const SettingSideBar: FC = () => {
|
|
const { t } = useTranslation()
|
|
const { activeSection, setColumnsCount, updateActiveItem, data, activeItemIndex } = usePersonalityStore()
|
|
const [color, setColor] = useState("#aabbcc");
|
|
const [backgroundSize, setBackgroundSize] = useState<BackgroundSize>(BackgroundSize.COVER)
|
|
const [isUploading, setIsUploading] = useState<boolean>(false)
|
|
|
|
const { mutateAsync: singleUpload } = useSingleUpload()
|
|
|
|
// تشخیص background size بر اساس style موجود
|
|
const getCurrentBackgroundSizeType = (style?: SectionItemType['style']) => {
|
|
if (!style) return BackgroundSize.COVER
|
|
|
|
const bgSize = style.backgroundSize
|
|
const bgRepeat = style.backgroundRepeat
|
|
|
|
if (bgSize === 'cover') return BackgroundSize.COVER
|
|
if (bgSize === 'contain') return BackgroundSize.CONTAIN
|
|
if (bgSize === 'auto' || !bgSize) {
|
|
if (bgRepeat === 'round') return BackgroundSize.ROUND
|
|
}
|
|
return BackgroundSize.COVER
|
|
}
|
|
|
|
// بهروزرسانی state وقتی activeSection یا activeItem تغییر میکند
|
|
useEffect(() => {
|
|
if (activeSection && data[activeSection as keyof typeof data]) {
|
|
const currentItem = data[activeSection as keyof typeof data]?.items[activeItemIndex]
|
|
if (currentItem?.style) {
|
|
const currentType = getCurrentBackgroundSizeType(currentItem.style)
|
|
setBackgroundSize(currentType)
|
|
}
|
|
}
|
|
}, [activeSection, activeItemIndex, data])
|
|
|
|
const handleColumnClick = (columns: number) => {
|
|
if (activeSection) {
|
|
setColumnsCount(activeSection as SectionName, columns);
|
|
}
|
|
}
|
|
|
|
const handleColorChange = (color: string) => {
|
|
setColor(color)
|
|
updateActiveItem({ backgroundColor: color })
|
|
}
|
|
|
|
const handleUploadBackground = async (file: File[]) => {
|
|
if (activeSection && file.length > 0) {
|
|
setIsUploading(true)
|
|
|
|
try {
|
|
const uploadResult = await singleUpload(file[0])
|
|
const imageUrl = uploadResult?.data?.url
|
|
|
|
if (imageUrl) {
|
|
const currentItem = data[activeSection as keyof typeof data]?.items[activeItemIndex]
|
|
updateActiveItem({
|
|
backgroundImage: imageUrl,
|
|
style: {
|
|
...currentItem?.style,
|
|
backgroundSize: getBackgroundSize(backgroundSize),
|
|
backgroundRepeat: getBackgroundRepeat(backgroundSize),
|
|
backgroundPosition: 'center center'
|
|
}
|
|
})
|
|
toast('تصویر پسزمینه با موفقیت آپلود شد', 'success')
|
|
}
|
|
} catch (error) {
|
|
console.error('Error uploading background image:', error)
|
|
toast('خطا در آپلود تصویر پسزمینه، از فایل محلی استفاده شد', 'error')
|
|
|
|
// Fallback to object URL if upload fails
|
|
const imageUrl = URL.createObjectURL(file[0])
|
|
|
|
const currentItem = data[activeSection as keyof typeof data]?.items[activeItemIndex]
|
|
updateActiveItem({
|
|
backgroundImage: imageUrl,
|
|
style: {
|
|
...currentItem?.style,
|
|
backgroundSize: getBackgroundSize(backgroundSize),
|
|
backgroundRepeat: getBackgroundRepeat(backgroundSize),
|
|
backgroundPosition: 'center center'
|
|
}
|
|
})
|
|
} finally {
|
|
setIsUploading(false)
|
|
}
|
|
}
|
|
}
|
|
|
|
const getBackgroundRepeat = (size: BackgroundSize) => {
|
|
switch (size) {
|
|
case BackgroundSize.ROUND:
|
|
return 'round'
|
|
case BackgroundSize.COVER:
|
|
case BackgroundSize.CONTAIN:
|
|
default:
|
|
return 'no-repeat'
|
|
}
|
|
}
|
|
|
|
const getBackgroundSize = (size: BackgroundSize) => {
|
|
switch (size) {
|
|
case BackgroundSize.COVER:
|
|
return 'cover'
|
|
case BackgroundSize.CONTAIN:
|
|
return 'contain'
|
|
case BackgroundSize.ROUND:
|
|
return 'auto'
|
|
default:
|
|
return 'cover'
|
|
}
|
|
}
|
|
|
|
const sizeOptions = [
|
|
{ label: 'کاور - تمام فضا را پوشش دهد (Cover)', value: BackgroundSize.COVER },
|
|
{ label: 'در مقیاس - در فضا جا شود (Contain)', value: BackgroundSize.CONTAIN },
|
|
{ label: 'گرد - عکس به صورت گرد تکرار شود (Round)', value: BackgroundSize.ROUND }
|
|
]
|
|
|
|
if (!activeSection) {
|
|
return (
|
|
<div className='text-center text-gray-500 mt-8'>
|
|
{t('setting.select_section')}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<div className='text-lg'>{t('setting.setting')}</div>
|
|
|
|
<div className='flex h-[51px] gap-5 mt-6'>
|
|
<div
|
|
className={`w-[102px] h-full bg-[#EAECF4] transition-colors ${isUploading ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer hover:bg-[#d1d5db]'}`}
|
|
onClick={() => !isUploading && handleColumnClick(1)}
|
|
></div>
|
|
<div
|
|
className={`w-[102px] h-full flex gap-1 group transition-colors ${isUploading ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`}
|
|
onClick={() => !isUploading && handleColumnClick(2)}
|
|
>
|
|
<div className={`flex-1 bg-[#EAECF4] transition-colors ${!isUploading && 'group-hover:bg-[#d1d5db]'}`}></div>
|
|
<div className={`flex-1 bg-[#EAECF4] transition-colors ${!isUploading && 'group-hover:bg-[#d1d5db]'}`}></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='flex h-[51px] gap-5 mt-5'>
|
|
<div
|
|
className={`w-[102px] h-full flex gap-1 group transition-colors ${isUploading ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`}
|
|
onClick={() => !isUploading && handleColumnClick(3)}
|
|
>
|
|
<div className={`flex-1 bg-[#EAECF4] transition-colors ${!isUploading && 'group-hover:bg-[#d1d5db]'}`}></div>
|
|
<div className={`flex-1 bg-[#EAECF4] transition-colors ${!isUploading && 'group-hover:bg-[#d1d5db]'}`}></div>
|
|
<div className={`flex-1 bg-[#EAECF4] transition-colors ${!isUploading && 'group-hover:bg-[#d1d5db]'}`}></div>
|
|
</div>
|
|
<div
|
|
className={`w-[102px] h-full flex gap-1 group transition-colors ${isUploading ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`}
|
|
onClick={() => !isUploading && handleColumnClick(4)}
|
|
>
|
|
<div className={`flex-1 bg-[#EAECF4] transition-colors ${!isUploading && 'group-hover:bg-[#d1d5db]'}`}></div>
|
|
<div className={`flex-1 bg-[#EAECF4] transition-colors ${!isUploading && 'group-hover:bg-[#d1d5db]'}`}></div>
|
|
<div className={`flex-1 bg-[#EAECF4] transition-colors ${!isUploading && 'group-hover:bg-[#d1d5db]'}`}></div>
|
|
<div className={`flex-1 bg-[#EAECF4] transition-colors ${!isUploading && 'group-hover:bg-[#d1d5db]'}`}></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='mt-5'>
|
|
<ColorPicker
|
|
label={t('setting.background')}
|
|
defaultColor={color}
|
|
changeColor={handleColorChange}
|
|
/>
|
|
</div>
|
|
|
|
<div className='mt-5'>
|
|
<UploadBoxDraggble
|
|
label={isUploading ? 'در حال آپلود...' : t('setting.upload_background')}
|
|
onChange={handleUploadBackground}
|
|
/>
|
|
</div>
|
|
|
|
<div className='mt-5'>
|
|
<Select
|
|
items={sizeOptions}
|
|
label={t('setting.size')}
|
|
value={backgroundSize}
|
|
onChange={(e) => {
|
|
const newSize = e.target.value as BackgroundSize
|
|
setBackgroundSize(newSize)
|
|
|
|
const currentItem = activeSection ? data[activeSection as keyof typeof data]?.items[activeItemIndex] : null
|
|
updateActiveItem({
|
|
style: {
|
|
...currentItem?.style,
|
|
backgroundSize: getBackgroundSize(newSize),
|
|
backgroundRepeat: getBackgroundRepeat(newSize),
|
|
backgroundPosition: 'center center'
|
|
}
|
|
})
|
|
}}
|
|
placeholder={t('setting.size')}
|
|
disabled={isUploading}
|
|
/>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default SettingSideBar |