Files
dmail-admin/src/pages/setting/personality/components/SettingSideBar.tsx
T
hamid zarghami 6f640a80a7 uploader template
2025-07-16 20:51:15 +03:30

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